<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Ethereum EIPs - Last Call Review</title>
    <description>All EIPs which are in the two-week "last call" status, please help review these and provide your feedback!</description>
    <link>https://eips.ethereum.org</link>
    <atom:link href="https://eips.ethereum.org/rss/last-call.xml" rel="self" type="application/rss+xml" />
    <lastBuildDate>Mon, 20 Apr 2026 03:22:01 +0000</lastBuildDate>
    
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Add chain id to mixed-case checksum address encoding</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #1191 - Add chain id to mixed-case checksum address encoding&lt;/strong&gt; is in Last Call status. It is authored by Juliano Rizzo (@juli) and was originally created 2018-03-18. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://github.com/ethereum/EIPs/issues/1121&quot;&gt;https://github.com/ethereum/EIPs/issues/1121&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;/h2&gt;

&lt;p&gt;This EIP extends &lt;a href=&quot;/EIPS/eip-55&quot;&gt;EIP-55&lt;/a&gt; by optionally adding a chain id defined by &lt;a href=&quot;/EIPS/eip-155&quot;&gt;EIP-155&lt;/a&gt; to the checksum calculation.&lt;/p&gt;

&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;/EIPS/eip-55&quot;&gt;EIP-55&lt;/a&gt; was created to prevent users from losing funds by sending them to invalid addresses. This EIP extends &lt;a href=&quot;/EIPS/eip-55&quot;&gt;EIP-55&lt;/a&gt; to protect users from losing funds by sending them to addresses that are valid but that where obtained from a client of another network.For example, if this EIP is implemented, a wallet can alert the user that is trying to send funds to an Ethereum Testnet address from an Ethereum Mainnet wallet.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;The motivation of this proposal is to provide a mechanism to allow software to distinguish addresses from different Ethereum based networks. This proposal is necessary because Ethereum addresses are hashes of public keys and do not include any metadata. By extending the &lt;a href=&quot;/EIPS/eip-55&quot;&gt;EIP-55&lt;/a&gt; checksum algorithm it is possible to achieve this objective.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/h2&gt;

&lt;p&gt;Convert the address using the same algorithm defined by &lt;a href=&quot;/EIPS/eip-55&quot;&gt;EIP-55&lt;/a&gt; but if a registered chain id is provided, add it to the input of the hash function. If the chain id passed to the function belongs to a network that opted for using this checksum variant, prefix the address with the chain id and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x&lt;/code&gt; separator before calculating the hash. Then convert the address to hexadecimal, but if the ith digit is a letter (ie. it’s one of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;abcdef&lt;/code&gt;) print it in uppercase if the 4*ith bit of the calculated hash is 1 otherwise print it in lowercase.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;By means of a minimal code change on existing libraries, users are protected from losing funds by mixing addresses of different Ethereum based networks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/python3
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sha3&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keccak_256&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
   addr (str): Hexadecimal address, 40 characters long with 2 characters prefix
   chainid (int): chain id from EIP-155 &quot;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;eth_checksum_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chainid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;adopted_eip1191&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hash_input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chainid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chainid&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;adopted_eip1191&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hash_output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keccak_256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;utf8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hexdigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;aggregate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash_output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aggregate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;/h2&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;eth_mainnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x27b1fdb04752bbc536007a920d24acb045561c26&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x3599689E6292b81B2d85451025146515070129Bb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x42712D45473476b98452f434e72461577D686318&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x52908400098527886E0F7030069857D2E4169EE7&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x6549f4939460DE12611948b3f82b88C3C8975323&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x66f9664f97F2b50F62D13eA064982f936dE76657&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x8617E340B3D01FA5F11F306F4090FD50E238070D&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x88021160C5C792225E4E5452585947470010289D&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xde709f2102306220921060314715629080e2fb77&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rsk_mainnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x27b1FdB04752BBc536007A920D24ACB045561c26&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x3599689E6292B81B2D85451025146515070129Bb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x42712D45473476B98452f434E72461577d686318&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x52908400098527886E0F7030069857D2E4169ee7&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x6549F4939460DE12611948B3F82B88C3C8975323&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x66F9664f97f2B50F62d13EA064982F936de76657&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x8617E340b3D01Fa5f11f306f4090fd50E238070D&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x88021160c5C792225E4E5452585947470010289d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xD1220A0Cf47c7B9BE7a2e6ba89F429762E7B9adB&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xDBF03B407c01E7CD3cBea99509D93F8Dddc8C6FB&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xDe709F2102306220921060314715629080e2FB77&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xFb6916095cA1Df60bb79ce92cE3EA74c37c5d359&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rsk_testnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x27B1FdB04752BbC536007a920D24acB045561C26&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x3599689e6292b81b2D85451025146515070129Bb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x42712D45473476B98452F434E72461577D686318&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x52908400098527886E0F7030069857D2e4169EE7&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x5aAeb6053F3e94c9b9A09F33669435E7EF1BEaEd&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x6549f4939460dE12611948b3f82b88C3c8975323&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x66f9664F97F2b50f62d13eA064982F936DE76657&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x8617e340b3D01fa5F11f306F4090Fd50e238070d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0x88021160c5C792225E4E5452585947470010289d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xd1220a0CF47c7B9Be7A2E6Ba89f429762E7b9adB&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xdbF03B407C01E7cd3cbEa99509D93f8dDDc8C6fB&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xDE709F2102306220921060314715629080e2Fb77&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;0xFb6916095CA1dF60bb79CE92ce3Ea74C37c5D359&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;test_cases&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rsk_mainnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rsk_testnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eth_mainnet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chainid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cases&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_cases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cases&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eth_checksum_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chainid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;

&lt;h3 id=&quot;usage--table&quot;&gt;Usage  Table&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Network&lt;/th&gt;
      &lt;th&gt;Chain id&lt;/th&gt;
      &lt;th&gt;Supports this EIP&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;RSK Mainnet&lt;/td&gt;
      &lt;td&gt;30&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;RSK Testnet&lt;/td&gt;
      &lt;td&gt;31&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;implementation-table&quot;&gt;Implementation Table&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Project&lt;/th&gt;
      &lt;th&gt;EIP Usage&lt;/th&gt;
      &lt;th&gt;Implementation&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;MyCrypto&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/MyCryptoHQ/MyCrypto/blob/develop/common/utils/formatters.ts#L126&quot;&gt;JavaScript&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;MyEtherWallet&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/MyEtherWallet/MyEtherWallet/blob/73c4a24f8f67c655749ac990c5b62efd92a2b11a/src/helpers/addressUtils.js#L22&quot;&gt;JavaScript&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ledger&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/LedgerHQ/ledger-app-eth/blob/master/src_common/ethUtils.c#L203&quot;&gt;C&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Trezor&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/trezor/trezor-core/blob/270bf732121d004a4cd1ab129adaccf7346ff1db/src/apps/ethereum/get_address.py#L32&quot;&gt;Python&lt;/a&gt; and &lt;a href=&quot;https://github.com/trezor/trezor-crypto/blob/4153e662b60a0d83c1be15150f18483a37e9092c/address.c#L62&quot;&gt;C&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Web3.js&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/ethereum/web3.js/blob/aaf26c8806bc9fb60cf6dcb6658104963c6c7fc7/packages/web3-utils/src/Utils.js#L140&quot;&gt;JavaScript&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;EthereumJS-util&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/ethereumjs/ethereumjs-util/pull/204/commits/cdf0b3c996b05ac5b1f758f17ea9f9ed1847c1eb&quot;&gt;JavaScript&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ENS address-encoder&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://github.com/ensdomains/address-encoder/commit/5bf53b13fa014646ea28c9e5f937361dc9b40590&quot;&gt;TypeScript&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;


      </description>
        <pubDate>Sun, 18 Mar 2018 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-1191</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-1191</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Atomic Swap-based American Call Option Contract Standard</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #2266 - Atomic Swap-based American Call Option Contract Standard&lt;/strong&gt; is in Last Call status. It is authored by Runchao Han &lt;runchao.han@monash.edu&gt;, Haoyu Lin &lt;chris.haoyul@gmail.com&gt;, Jiangshan Yu &lt;jiangshan.yu@monash.edu&gt; and was originally created 2019-08-17. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://github.com/ethereum/EIPs/issues/2266&quot;&gt;https://github.com/ethereum/EIPs/issues/2266&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;simple-summary&quot;&gt;Simple Summary&lt;/h2&gt;

&lt;p&gt;A standard for token contracts providing Atomic Swap-based American Call Option functionalities.&lt;/p&gt;

&lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This standard provides functionality to make Atomic Swap-based American Call Option payment. The Atomic Swap protocol based on Hashed Time-Locked Contract (HTLC) &lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; has optionality &lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;, and such optionality can be utilised to construct American Call Options without trusted third party. This standard defines the common way of implementing this protocol. In particular, this EIP defines technical terms, provides interfaces, and gives reference implementations of this protocol.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;Atomic Swap allows users to atomically exchange their tokens without trusted third parties while the HTLC is commonly used for the implementation. However, the HTLC-based Atomic Swap has optionality. More specifically, the swap initiator can choose to proceed or abort the swap for several hours, which gives him time for speculating according to the exchange rate. A discussion&lt;sup id=&quot;fnref:2:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; shows that the HTLC-based Atomic Swap is equivalent to an American Call Option in finance. On the other hand,thanks to such optionality, the HTLC-based Atomic Swap can be utilised to construct American Call Options without trusted third party. A paper&lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; proposes a secure Atomic-Swap-based American Call Option protocol on smart contracts. This protocol not only eliminates the arbitrage opportunity but also prevents any party from locking the other party’s money maliciously. This EIP aims at providing the standard of implementing this protocol in existing token standards.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/h2&gt;

&lt;p&gt;The Atomic Swap-based American Call Option smart contract should follow the syntax and semantics of Ethereum smart contracts.&lt;/p&gt;

&lt;h3 id=&quot;definitions&quot;&gt;Definitions&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initiator&lt;/code&gt;: the party who publishes the advertisement of the swap.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;participant&lt;/code&gt;: the party who agrees on the advertisement and participates in the swap with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initiator&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asset&lt;/code&gt;: the amount of token(s) to be exchanged.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;premium&lt;/code&gt;: the amount of token(s) that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initiator&lt;/code&gt; pays to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;participant&lt;/code&gt; as the premium.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;redeem&lt;/code&gt;: the action to claim the token from the other party.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;refund&lt;/code&gt;: the action to claim the token from the party herself/himself, because of timelock expiration.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secrect&lt;/code&gt;: a random string chosen by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initiator&lt;/code&gt; as the preimage of a hash.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secrectHash&lt;/code&gt;: a string equals to the hash of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secrect&lt;/code&gt;, used for constructing HTLCs.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;timelock&lt;/code&gt;: a timestamp representing the timelimit, before when the asset can be redeemed, and otherwise can only be refunded.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;storage-variables&quot;&gt;Storage Variables&lt;/h3&gt;

&lt;h4 id=&quot;swap&quot;&gt;swap&lt;/h4&gt;

&lt;p&gt;This mapping stores the metadata of the swap contracts, including the parties and tokens involved. Each contract uses different &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secretHash&lt;/code&gt;, and is distinguished by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secretHash&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Swap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;swap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;initiatorasset&quot;&gt;initiatorAsset&lt;/h4&gt;

&lt;p&gt;This mapping stores the detail of the asset initiators want to sell, including the amount, the timelock and the state. It is associated with the swap contract with the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secretHash&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InitiatorAsset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiatorAsset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;participantasset&quot;&gt;participantAsset&lt;/h4&gt;

&lt;p&gt;This mapping stores the details of the asset participants want to sell, including the amount, the timelock and the state. It is associated with the swap contract with the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secretHash&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParticipantAsset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participantAsset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;premiumasset&quot;&gt;premiumAsset&lt;/h4&gt;

&lt;p&gt;This mapping stores the details of the premium initiators attach in the swap contract, including the amount, the timelock and the state. It is associated with the swap contract with the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secretHash&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Premium&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;premium&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;methods&quot;&gt;Methods&lt;/h3&gt;

&lt;h4 id=&quot;setup&quot;&gt;setup&lt;/h4&gt;

&lt;p&gt;This function sets up the swap contract, including the both parties involved, the tokens to exchanged, and so on.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiatorAssetAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participantAssetAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;premiumAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;payable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;initiate&quot;&gt;initiate&lt;/h4&gt;

&lt;p&gt;The initiator invokes this function to fill and lock the token she/he wants to sell and join the contract.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assetRefundTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;payable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;fillpremium&quot;&gt;fillPremium&lt;/h4&gt;

&lt;p&gt;The initiator invokes this function to fill and lock the premium.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fillPremium&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;premiumRefundTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;payable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;participate&quot;&gt;participate&lt;/h4&gt;

&lt;p&gt;The participant invokes this function to fill and lock the token she/he wants to sell and join the contract.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assetRefundTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;payable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;redeemasset&quot;&gt;redeemAsset&lt;/h4&gt;

&lt;p&gt;One of the parties invokes this function to get the token from the other party, by providing the preimage of the hash lock &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secret&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redeemAsset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;refundasset&quot;&gt;refundAsset&lt;/h4&gt;

&lt;p&gt;One of the parties invokes this function to get the token back after the timelock expires.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;refundAsset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;redeempremium&quot;&gt;redeemPremium&lt;/h4&gt;

&lt;p&gt;The participant invokes this function to get the premium. This can be invoked only if the participant has already invoked &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;participate&lt;/code&gt; and the participant’s token is redeemed or refunded.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redeemPremium&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;refundpremium&quot;&gt;refundPremium&lt;/h4&gt;

&lt;p&gt;The initiator invokes this function to get the premium back after the timelock expires.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;refundPremium&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;events&quot;&gt;Events&lt;/h3&gt;

&lt;h4 id=&quot;setup-1&quot;&gt;SetUp&lt;/h4&gt;

&lt;p&gt;This event indicates that one party has set up the contract using the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup()&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SetUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiatorAssetAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participantAssetAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;premiumAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;initiated&quot;&gt;Initiated&lt;/h4&gt;

&lt;p&gt;This event indicates that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initiator&lt;/code&gt; has filled and locked the token to be exchanged using the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initiate()&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Initiated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiateTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiatorAssetToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiatorAssetAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiatorAssetRefundTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;participated&quot;&gt;Participated&lt;/h4&gt;

&lt;p&gt;This event indicates that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;participant&lt;/code&gt; has filled and locked the token to be exchanged using the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;participate()&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Participated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participateTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participantAssetToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participantAssetAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participantAssetRefundTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;premiumfilled&quot;&gt;PremiumFilled&lt;/h4&gt;

&lt;p&gt;This event indicates that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initiator&lt;/code&gt; has filled and locked &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;premium&lt;/code&gt; using the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fillPremium()&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PremiumFilled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fillPremiumTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initiator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;participant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;premiumToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;premiumAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;premiumRefundTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;initiatorassetredeemedparticipantassetredeemed&quot;&gt;InitiatorAssetRedeemed/ParticipantAssetRedeemed&lt;/h4&gt;

&lt;p&gt;These two events indicate that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asset&lt;/code&gt; has been redeemed by the other party before the timelock by providing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secret&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InitiatorAssetRedeemed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redeemTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redeemer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assetToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParticipantAssetRedeemed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redeemTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redeemer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assetToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;initiatorassetrefundedparticipantassetrefunded&quot;&gt;InitiatorAssetRefunded/ParticipantAssetRefunded&lt;/h4&gt;

&lt;p&gt;These two events indicate that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asset&lt;/code&gt; has been refunded by the original owner after the timelock expires.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InitiatorAssetRefunded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;refundTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;refunder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assetToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParticipantAssetRefunded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;refundTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;refunder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assetToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;premiumredeemed&quot;&gt;PremiumRedeemed&lt;/h4&gt;

&lt;p&gt;This event indicates that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;premium&lt;/code&gt; has been redeemed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;participant&lt;/code&gt;. This implies that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asset&lt;/code&gt; is either redeemed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initiator&lt;/code&gt; if it can provide the preimage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;secrectHash&lt;/code&gt; before  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asset&lt;/code&gt; timelock expires; or refunded by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;participant&lt;/code&gt; if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asset&lt;/code&gt; timelock expires.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PremiumRedeemed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redeemTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redeemer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;premiumrefunded&quot;&gt;PremiumRefunded&lt;/h4&gt;

&lt;p&gt;This event indicates that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;premium&lt;/code&gt; has been refunded back to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initiator&lt;/code&gt;, because of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;participant&lt;/code&gt; doesn’t participate at all, by the time of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;premium&lt;/code&gt; timelock expires.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PremiumRefunded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;refundTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secretHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;refunder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;To achieve the atomicity, HTLC is used.&lt;/li&gt;
  &lt;li&gt;The participant should decide whether to participate after the initiator locks the token and sets up the timelock.&lt;/li&gt;
  &lt;li&gt;The initiator should decide whether to proceed the swap (redeem the tokens from the participant and reveal the preimage of the hash lock), after the participant locks the tokens and sets up the time locks.&lt;/li&gt;
  &lt;li&gt;Premium is redeemable for the participant only if the participant participates in the swap and redeems the initiator’s token before premium’s timelock expires.&lt;/li&gt;
  &lt;li&gt;Premium is refundable for the initiator only if the initiator initiates but the participant does not participate in the swap at all.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initiateTimestamp&lt;/code&gt; should cover the whole swap process.&lt;/li&gt;
  &lt;li&gt;The participant should never participate before the premium has been deposited.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This proposal is fully backward compatible. Functionalities of existing standards will not be affected by this proposal, as it only provides additional features to them.&lt;/p&gt;

&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;/h2&gt;

&lt;p&gt;Please visit &lt;a href=&quot;/assets/eip-2266/Example.sol&quot;&gt;here&lt;/a&gt; to find our example implementation.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://en.bitcoin.it/wiki/Hash_Time_Locked_Contracts&quot;&gt;Hash Time Locked Contracts&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-January/001798.html&quot;&gt;An Argument For Single-Asset Lightning Network&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt; &lt;a href=&quot;#fnref:2:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://eprint.iacr.org/2019/896&quot;&gt;On the optionality and fairness of Atomic Swaps&lt;/a&gt; &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;

      </description>
        <pubDate>Sat, 17 Aug 2019 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-2266</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-2266</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Slashing Protection Interchange Format</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #3076 - Slashing Protection Interchange Format&lt;/strong&gt; is in Last Call status. It is authored by Michael Sproul (@michaelsproul), Sacha Saint-Leger (@sachayves), Danny Ryan (@djrtwo) and was originally created 2020-10-27. It is in the Interface category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-3076-validator-client-interchange-format-slashing-protection/4883&quot;&gt;https://ethereum-magicians.org/t/eip-3076-validator-client-interchange-format-slashing-protection/4883&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;A standard format for transferring a key’s signing history allows validators to easily switch between clients without the risk of signing conflicting messages. While a common keystore format provides part of the solution, it does not contain any information about a key’s signing history. For a validator moving their keys from client A to client B, this could lead to scenarios in which client B inadvertently signs a message that conflicts with an earlier message signed with client A. The interchange format described here provides a solution to this problem.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;The proof of stake (PoS) protocol penalises validators for voting in ways that could result in two different versions of the chain being finalised. These types of penalties are called slashings.&lt;/p&gt;

&lt;p&gt;For a validator following the protocol correctly, there is, in principle, no risk of being slashed. However, changing clients (from client A to client B, say) can result in a slashing risk if client B is unaware of the blocks and attestations that were signed with client A.&lt;/p&gt;

&lt;p&gt;This can occur if client A and client B do not agree on what the present time is. For example, say client A’s time is accidentally set to a day in the future (225 epochs), and a validator switches from client A to client B without giving B a record of the blocks and attestations signed with A. The validator in question now runs the risk of attesting to two different blocks in the same epoch (a slashable offence) for the next 225 epochs (since they’ve already voted on these epochs with client A, and now stand to vote on them again with client B). Such time-skew bugs have been observed in the wild.&lt;/p&gt;

&lt;p&gt;Another situation in which slashing protection is critical is in the case of re-orgs. During a re-org it is possible for a validator to be assigned new attestation duties for an epoch in which it has already signed an attestation. In this case it is essential that the record of the previous attestation is available, even if the validator just moved from one client to another in the space of a single epoch.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/h2&gt;

&lt;h3 id=&quot;json-schema&quot;&gt;JSON Schema&lt;/h3&gt;

&lt;p&gt;A valid interchange file is one that adheres to the following JSON schema, and is interpreted according to the &lt;a href=&quot;#conditions&quot;&gt;Conditions&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Signing history&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;This schema provides a record of the blocks and attestations signed by a set of validators&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;metadata&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;interchange_format_version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;The version of the interchange format that this document adheres to&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;genesis_validators_root&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Calculated at Genesis time; serves to uniquely identify the chain&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;interchange_format_version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;genesis_validators_root&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;array&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;items&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;pubkey&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;The BLS public key of the validator (encoded as a 0x-prefixed hex string)&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;signed_blocks&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;array&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;items&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;slot&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;The slot number of the block that was signed&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;signing_root&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;The output of compute_signing_root(block, domain)&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;slot&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;signed_attestations&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;array&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;items&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;object&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;source_epoch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;The attestation.data.source.epoch of the signed attestation&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;target_epoch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;The attestation.data.target.epoch of the signed attestation&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;signing_root&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;The output of compute_signing_root(attestation, domain)&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;source_epoch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;target_epoch&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pubkey&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;signed_blocks&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;signed_attestations&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;metadata&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;example-json-instance&quot;&gt;Example JSON Instance&lt;/h3&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;metadata&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;interchange_format_version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;genesis_validators_root&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0x04700007fabc8282644aed6d1c7c9e21d38a03a0c4ba193f3afe428824b3a673&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;pubkey&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0xb845089a1457f811bfc000588fbb4e713669be8ce060ea6be3c6ece09afc3794106c91ca73acda5e5457122d58723bed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;signed_blocks&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;slot&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;81952&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;signing_root&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0x4ff6f743a43f3b4f95350831aeaf0a122a1a392922c45d804280284a69eb850b&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;slot&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;81951&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;signed_attestations&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;source_epoch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2290&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;target_epoch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;3007&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;signing_root&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0x587d6a4f59a58fe24f406e0502413e77fe1babddee641fda30034ed37ecc884d&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;source_epoch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2290&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;target_epoch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;3008&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;conditions&quot;&gt;Conditions&lt;/h3&gt;

&lt;p&gt;After importing an interchange file with data field &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt;, a signer must respect the following conditions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Refuse to sign any block that is slashable with respect to the blocks contained in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data.signed_blocks&lt;/code&gt;. For details of what constitutes a slashable block, see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;process_proposer_slashing&lt;/code&gt; (from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;consensus-specs&lt;/code&gt;). If the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;signing_root&lt;/code&gt; is absent from a block, a signer must assume that any new block with the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slot&lt;/code&gt; is slashable with respect to the imported block.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Refuse to sign any block with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;slot &amp;lt;= min(b.slot for b in data.signed_blocks if b.pubkey == proposer_pubkey)&lt;/code&gt;, except if it is a repeat signing as determined by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;signing_root&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Refuse to sign any attestation that is slashable with respect to the attestations contained in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data.signed_attestations&lt;/code&gt;. For details of what constitutes a slashable attestation, see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;is_slashable_attestation_data&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Refuse to sign any attestation with source epoch less than the minimum source epoch present in that signer’s attestations (as seen in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data.signed_attestations&lt;/code&gt;). In pseudocode:&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class=&quot;language-python3&quot;&gt;source.epoch &amp;lt;
    min(att.source_epoch
        for att in data.signed_attestations
        if att.pubkey == attester_pubkey)
&lt;/code&gt;&lt;/pre&gt;

&lt;ol start=&quot;5&quot;&gt;
  &lt;li&gt;Refuse to sign any attestation with target epoch less than or equal to the minimum target epoch present in that signer’s attestations (as seen in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data.signed_attestations&lt;/code&gt;), except if it is a repeat signing as determined by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;signing_root&lt;/code&gt;. In pseudocode:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class=&quot;language-python3&quot;&gt;target_epoch &amp;lt;=
    min(att.target_epoch
        for att in data.signed_attestations
        if att.pubkey == attester_pubkey)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;additional-information&quot;&gt;Additional Information&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interchange_format_version&lt;/code&gt; version is set to 5.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A signed block or attestation’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;signing_root&lt;/code&gt; refers to the message data (hash tree root) that gets signed with a BLS signature. It allows validators to re-sign and re-broadcast blocks or attestations if asked.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;signed_blocks&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;signing_root&lt;/code&gt;s are calculated using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compute_signing_root(block, domain)&lt;/code&gt;: where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;block&lt;/code&gt; is the block (of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BeaconBlock&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BeaconBlockHeader&lt;/code&gt;) that was signed, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;domain&lt;/code&gt; is equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compute_domain(DOMAIN_BEACON_PROPOSER, fork, metadata.genesis_validators_root)&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;signed_attestations&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;signing_root&lt;/code&gt;s are calculated using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compute_signing_root(attestation, domain)&lt;/code&gt;: where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;attestation&lt;/code&gt; is the attestation (of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AttestationData&lt;/code&gt;) that was signed, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;domain&lt;/code&gt; is equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compute_domain(DOMAIN_BEACON_ATTESTER, fork, metadata.genesis_validators_root)&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;h3 id=&quot;supporting-different-strategies&quot;&gt;Supporting Different Strategies&lt;/h3&gt;

&lt;p&gt;The interchange format is designed to be flexible enough to support the full variety of slashing protection strategies that clients may implement, which may be categorised into two main types:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Complete&lt;/strong&gt;: a database containing every message signed by each validator.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Minimal&lt;/strong&gt;: a database containing only the latest messages signed by each validator.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The advantage of the minimal strategy is its simplicity and succinctness. Using only the latest messages for each validator, safe slashing protection can be achieved by refusing to sign messages for slots or epochs prior.&lt;/p&gt;

&lt;p&gt;On the other hand, the complete strategy can provide safe slashing protection while also avoiding false positives (meaning that it only prevents a validator from signing if doing so would guarantee a slashing).&lt;/p&gt;

&lt;p&gt;The two strategies are unified in the interchange format through the inclusion of &lt;a href=&quot;#conditions&quot;&gt;conditions&lt;/a&gt; (2), (4) and (5). This allows the interchange to transfer detailed or succinct information, as desired.&lt;/p&gt;

&lt;h3 id=&quot;integer-representation&quot;&gt;Integer Representation&lt;/h3&gt;

&lt;p&gt;Most fields in the JSON schema are strings. For fields in which it is possible to encode the value as either a string or an integer, strings were chosen. This choice was made in order to avoid issues with different languages supporting different ranges of integers (specifically JavaScript, where the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;number&lt;/code&gt; type is a 64-bit float). If a validator is yet to sign a block or attestation, the relevant list is simply left empty.&lt;/p&gt;

&lt;h3 id=&quot;versioning&quot;&gt;Versioning&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interchange_format_version&lt;/code&gt; is set to 5 because the specification went through several breaking changes during its design, incorporating feedback from implementers.&lt;/p&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This specification is not backwards-compatible with previous draft versions that used version numbers less than 5.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;In order to minimise risk and complexity, the format has been designed to map cleanly onto the internal database formats used by implementers. Nevertheless, there are a few pitfalls worth illuminating.&lt;/p&gt;

&lt;h3 id=&quot;advice-for-complete-databases&quot;&gt;Advice for Complete Databases&lt;/h3&gt;

&lt;p&gt;For implementers who use a complete record of signed messages to implement their slashing protection database, we make the following recommendations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You MUST ensure that, in addition to importing all of the messages from an interchange, all the &lt;a href=&quot;#conditions&quot;&gt;conditions&lt;/a&gt; are enforced. In particular, conditions (2), (4) and (5) may not have been enforced by your implementation before adopting the interchange format. Our recommendation is to enforce these rules at all times, to keep the implementation clean and minimise the attack surface. For example: your slashing protection mechanism should not sign a block with a slot number less than, or equal to, the minimum slot number of a previously signed block, &lt;em&gt;irrespective&lt;/em&gt; of whether that minimum-slot block was imported from an interchange file, or inserted as part of your database’s regular operation.&lt;/li&gt;
  &lt;li&gt;If your database records the signing roots of messages in addition to their slot/epochs, you should ensure that imported messages without signing roots are assigned a suitable dummy signing root internally. We suggest using a special “null” value which is distinct from all other signing roots, although a value like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x0&lt;/code&gt; may be used instead (as it is extremely unlikely to collide with any real signing root).&lt;/li&gt;
  &lt;li&gt;Care must be taken to avoid signing messages within a gap in the database (an area of unknown signing activity). This could occur if two interchanges were imported with a large gap between the last entry of the first and the first entry of the second. Signing in this gap is not safe, and would violate conditions (2), (4) and (5). It can be avoided by storing an explicit low watermark in addition to the actual messages of the slashing protection database, or by pruning on import so that the oldest messages from the interchange become the oldest messages in the database.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;advice-for-minimal-databases&quot;&gt;Advice for Minimal Databases&lt;/h3&gt;

&lt;p&gt;For implementers who wish to implement their slashing protection database by storing only the latest block and attestation for each validator, we make the following recommendations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;During import, make sure you take the &lt;em&gt;maximum&lt;/em&gt; slot block and &lt;em&gt;maximum&lt;/em&gt; source and target attestations for each validator. Although the &lt;a href=&quot;#conditions&quot;&gt;conditions&lt;/a&gt; require the minimums to be enforced, taking the maximums from an interchange file and merging them with any existing values in the database is the recommended approach. For example, if the interchange file includes blocks for validator &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;V&lt;/code&gt; at slots 4, 98 and 243, then the latest signed block for validator &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;V&lt;/code&gt; should be updated to the one from slot 243.  However, if the database has already included a block for this validator at a slot greater than 243, for example, slot 351, then the database’s existing value should remain unchanged.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;general-recommendations&quot;&gt;General Recommendations&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;To avoid exporting an outdated interchange file – an action which creates a slashing risk – your implementation should only allow the slashing protection database to be exported when the validator client or signer is &lt;em&gt;stopped&lt;/em&gt; – in other words, when the client or signer is no longer adding new messages to the database.&lt;/li&gt;
  &lt;li&gt;Similarly, your implementation should only allow an interchange file to be imported when the validator client is stopped.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Tue, 27 Oct 2020 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-3076</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-3076</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>EVM trace specification</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #3155 - EVM trace specification&lt;/strong&gt; is in Last Call status. It is authored by Martin Holst Swende (@holiman), Marius van der Wijden (@MariusVanDerWijden) and was originally created 2020-12-07. It is in the Interface category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-3155-create-evm-trace-specification/5007&quot;&gt;https://ethereum-magicians.org/t/eip-3155-create-evm-trace-specification/5007&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;Introduce a new JSON standard for EVM traces during execution of state tests.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;The Ethereum Virtual Machine executes all smart contract code on ethereum.
In order to debug smart contracts and state tests better, a common format was introduced to log every execution step of the EVM.
This format was implemented by Go-Ethereum, Parity-Ethereum, Nethermind and Besu.
Since the common format was not well-defined, the implementations differed slightly, making it hard to develop adequate tooling which reduces the usefulness of tracing significantly.&lt;/p&gt;

&lt;p&gt;This EIP has multiple goals:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Move the specification to a more visible place to encourage new clients to implement it&lt;/li&gt;
  &lt;li&gt;Strictly define corner cases that were not addressed in the previous version&lt;/li&gt;
  &lt;li&gt;Allow for updates to the specification in case new fields are introduced during execution&lt;/li&gt;
  &lt;li&gt;Provide sample output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implementing this EIP in all major clients allows us to create meaningful differential fuzzers that fuzz EVM implementations for the mainnet and all upcoming hardforks.
It also helps to find differences in execution quickly in the case of a chain split.&lt;/p&gt;

&lt;p&gt;This EIP will enable users to create better differential fuzzing infrastructure to compare the EVM implementations of all major Ethereum clients against each other.
This could help to find bugs that are currently present in the client implementations.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/h2&gt;

&lt;p&gt;Clients should be able to execute simple transactions as well as code and return traces. In the following, we will call this client CUT (client under test) and use go-ethereum’s
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;evm&lt;/code&gt; binary for code examples.&lt;/p&gt;

&lt;h3 id=&quot;datatypes&quot;&gt;Datatypes&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Explanation&lt;/th&gt;
      &lt;th&gt;Example&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Number&lt;/td&gt;
      &lt;td&gt;Plain json number&lt;/td&gt;
      &lt;td&gt;“pc”:0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Hex-Number&lt;/td&gt;
      &lt;td&gt;Hex-encoded number&lt;/td&gt;
      &lt;td&gt;“gas”:”0x2540be400”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;String&lt;/td&gt;
      &lt;td&gt;Plain string&lt;/td&gt;
      &lt;td&gt;“opName”:”PUSH1”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Hex-String&lt;/td&gt;
      &lt;td&gt;Hex-encoded string&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Array of x&lt;/td&gt;
      &lt;td&gt;Array of x encoded values&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Key-Value&lt;/td&gt;
      &lt;td&gt;Key-Value structure with key and values encoded as hex strings&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Boolean&lt;/td&gt;
      &lt;td&gt;Json bool can either be true or false&lt;/td&gt;
      &lt;td&gt;“pass”: true&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;output&quot;&gt;Output&lt;/h3&gt;

&lt;p&gt;The CUT MUST output a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;json&lt;/code&gt; object for EACH operation.&lt;/p&gt;

&lt;h4 id=&quot;required-fields&quot;&gt;Required Fields&lt;/h4&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Explanation&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pc&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Number&lt;/td&gt;
      &lt;td&gt;Program Counter&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;op&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Number&lt;/td&gt;
      &lt;td&gt;OpCode&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gas&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hex-Number&lt;/td&gt;
      &lt;td&gt;Gas left before executing this operation&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gasCost&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hex-Number&lt;/td&gt;
      &lt;td&gt;Gas cost of this operation&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memSize&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Number&lt;/td&gt;
      &lt;td&gt;Size of memory array&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stack&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Array of Hex-Numbers&lt;/td&gt;
      &lt;td&gt;Array of all values on the stack&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;depth&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Number&lt;/td&gt;
      &lt;td&gt;Depth of the call stack&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;returnData&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hex-String&lt;/td&gt;
      &lt;td&gt;Data returned by function call&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;refund&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hex-Number&lt;/td&gt;
      &lt;td&gt;Amount of &lt;strong&gt;global&lt;/strong&gt; gas refunded&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;optional-fields&quot;&gt;Optional Fields&lt;/h4&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Explanation&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;opName&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;String&lt;/td&gt;
      &lt;td&gt;Name of the operation&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hex-String&lt;/td&gt;
      &lt;td&gt;Description of an error (should contain revert reason if supported)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memory&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Array of Hex-Strings&lt;/td&gt;
      &lt;td&gt;Array of all allocated values&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;storage&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Key-Value&lt;/td&gt;
      &lt;td&gt;Array of all stored values&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{&quot;pc&quot;:0,&quot;op&quot;:96,&quot;gas&quot;:&quot;0x2540be400&quot;,&quot;gasCost&quot;:&quot;0x3&quot;,&quot;memory&quot;:&quot;0x&quot;,&quot;memSize&quot;:0,&quot;stack&quot;:[],&quot;depth&quot;:1,&quot;error&quot;:null,&quot;opName&quot;:&quot;PUSH1&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stack&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memory&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memSize&lt;/code&gt; are the values &lt;em&gt;before&lt;/em&gt; execution of the op.&lt;/li&gt;
  &lt;li&gt;All array attributes (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stack&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memory&lt;/code&gt;) MUST be initialized to empty arrays (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;stack&quot;:[]&lt;/code&gt;) NOT to null.&lt;/li&gt;
  &lt;li&gt;If the CUT will not be outputting values for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memory&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;storage&lt;/code&gt; then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memory&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;storage&lt;/code&gt; fields are omitted.
This can happen either because the CUT does not support tracing these fields or it has been configured not to trace it.&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memSize&lt;/code&gt; field MUST be present regardless of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;memory&lt;/code&gt; support.&lt;/li&gt;
  &lt;li&gt;Clients SHOULD implement a way to disable recording the storage as the stateroot includes all storage updates.&lt;/li&gt;
  &lt;li&gt;Clients SHOULD output the fields in the same order as listed in this EIP.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CUT MUST NOT output a line for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;STOP&lt;/code&gt; operation if an error occurred:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{&quot;pc&quot;:2,&quot;op&quot;:0,&quot;gas&quot;:&quot;0x2540be3fd&quot;,&quot;gasCost&quot;:&quot;0x0&quot;,&quot;memory&quot;:&quot;0x&quot;,&quot;memSize&quot;:0,&quot;stack&quot;:[&quot;0x40&quot;],&quot;depth&quot;:1,&quot;error&quot;:null,&quot;opName&quot;:&quot;STOP&quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;summary-and-error-handling&quot;&gt;Summary and Error Handling&lt;/h3&gt;

&lt;p&gt;At the end of execution, the CUT MUST print summary info; this info SHOULD have the following fields.
The summary should be a single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jsonl&lt;/code&gt; object.&lt;/p&gt;

&lt;h4 id=&quot;required-fields-1&quot;&gt;Required Fields&lt;/h4&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Explanation&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;stateRoot&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hex-String&lt;/td&gt;
      &lt;td&gt;Root of the state trie after executing the transaction&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;output&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;Return values of the function&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gasUsed&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hex-Number&lt;/td&gt;
      &lt;td&gt;All gas used by the transaction&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pass&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Boolean&lt;/td&gt;
      &lt;td&gt;Bool whether transaction was executed successfully&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h4 id=&quot;optional-fields-1&quot;&gt;Optional Fields&lt;/h4&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Explanation&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;time&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Number&lt;/td&gt;
      &lt;td&gt;Time in nanoseconds needed to execute the transaction&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fork&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;String&lt;/td&gt;
      &lt;td&gt;Name of the fork rules used for execution&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;em&gt;Example&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{&quot;stateRoot&quot;:&quot;0xd4c577737f5d20207d338c360c42d3af78de54812720e3339f7b27293ef195b7&quot;,&quot;output&quot;:&quot;&quot;,&quot;gasUsed&quot;:&quot;0x3&quot;,&quot;pass&quot;:&quot;true&quot;,&quot;time&quot;:141485}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;This EIP is largely based on the previous non-official documentation for EVM tracing.
It tries to cover as many corner cases as possible to enable true client compatibility.
The datatypes and if a field is optional is chosen to be as compatible with current implementations as possible.&lt;/p&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This EIP is fully backward compatible with ethereum as it only introduces a better tracing infrastructure that is optional for clients to implement.&lt;/p&gt;

&lt;h3 id=&quot;clients&quot;&gt;Clients&lt;/h3&gt;

&lt;p&gt;This EIP is fully backward compatible with go-ethereum. OpenEthereum, Besu and Nethermind clients would have to change their JSON output of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;openethereum-evm&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;evmtool&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nethtest&lt;/code&gt; slightly do adhere to the new and stricter specs. New clients would need to implement this change if they want to be part of the differential fuzzing group.&lt;/p&gt;

&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;/h2&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;BESU_HOME&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/bin/evmtool &lt;span class=&quot;nt&quot;&gt;--code&lt;/span&gt; 0x604080536040604055604060006040600060025afa6040f3 &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540be400&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x3&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[],&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;PUSH1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:2,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:128,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540be3fd&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x3&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;DUP1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:3,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:83,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540be3fa&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0xc&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;MSTORE8&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:4,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540be3ee&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x3&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[],&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;PUSH1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:6,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540be3eb&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x3&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;PUSH1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:8,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:85,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540be3e8&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x4e20&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;SSTORE&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:9,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540b95c8&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x3&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[],&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;PUSH1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:11,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540b95c5&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x3&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;PUSH1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:13,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540b95c2&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x3&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x0&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;PUSH1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:15,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540b95bf&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x3&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x0&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;PUSH1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:17,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540b95bc&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x3&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x0&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x0&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;PUSH1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:19,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:90,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540b95b9&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x0&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x0&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x2&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;GAS&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:20,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:250,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540b95b7&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x24abb676c&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x0&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x0&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x2&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x2540b95b7&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;STATICCALL&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:21,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540b92a7&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x3&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;returnData&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;PUSH1&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pc&quot;&lt;/span&gt;:23,&lt;span class=&quot;s2&quot;&gt;&quot;op&quot;&lt;/span&gt;:243,&lt;span class=&quot;s2&quot;&gt;&quot;gas&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x2540b92a4&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasCost&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x0&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memory&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;memSize&quot;&lt;/span&gt;:96,&lt;span class=&quot;s2&quot;&gt;&quot;stack&quot;&lt;/span&gt;:[&lt;span class=&quot;s2&quot;&gt;&quot;0x1&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;returnData&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;depth&quot;&lt;/span&gt;:1,&lt;span class=&quot;s2&quot;&gt;&quot;refund&quot;&lt;/span&gt;:0,&lt;span class=&quot;s2&quot;&gt;&quot;opName&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;RETURN&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;stateRoot&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x8fa0dcc7f1d2383c89e5737c2843632db881c0946e80b71fe7175365e6538797&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;output&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x40&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;gasUsed&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;0x515c&quot;&lt;/span&gt;,&lt;span class=&quot;s2&quot;&gt;&quot;pass&quot;&lt;/span&gt;:true,&lt;span class=&quot;s2&quot;&gt;&quot;fork&quot;&lt;/span&gt;:&lt;span class=&quot;s2&quot;&gt;&quot;Istanbul&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;Tracing is expensive.&lt;/p&gt;

&lt;p&gt;Exposing an endpoint for creating traces publicly could open up a denial of service vector.&lt;/p&gt;

&lt;p&gt;Clients should consider putting trace endpoints behind a separate flag from other endpoints.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Mon, 07 Dec 2020 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-3155</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-3155</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>ERC-721 Nonce Extension</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #5008 - ERC-721 Nonce Extension&lt;/strong&gt; is in Last Call status. It is authored by Anders (@0xanders), Lance (@LanceSnow), Shrug &lt;shrug@emojidao.org&gt; and was originally created 2022-04-10. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip5008-eip-721-nonce-and-metadata-update-extension/8925&quot;&gt;https://ethereum-magicians.org/t/eip5008-eip-721-nonce-and-metadata-update-extension/8925&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This standard is an extension of &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt;. It proposes adding a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt; function to ERC-721 tokens.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;Some orders of NFT marketplaces have been attacked and the NFTs sold at a lower price than the current market floor price. This can happen when users transfer an NFT to another wallet and, later, back to the original wallet. This reactivates the order, which may list the token at a much lower price than the owner would have intended.&lt;/p&gt;

&lt;p&gt;This EIP proposes adding a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt; property to ERC-721 tokens, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt; will be changed when a token is transferred. If a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt; is added to an order, the order can be checked to avoid attacks.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;c1&quot;&gt;/// @dev the ERC-165 identifier for this interface is 0xce03fdab.
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5008&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* is IERC165 */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// @notice Emitted when the `nonce` of an NFT is changed
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NonceChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Get the nonce of an NFT
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// Throws if `tokenId` is not a valid NFT
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The id of the NFT
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return The nonce of the NFT
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce(uint256 tokenId)&lt;/code&gt; function MUST be implemented as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;supportsInterface&lt;/code&gt; method MUST return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; when called with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xce03fdab&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;At first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transferCount&lt;/code&gt; was considered as function name, but there may some case to change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt; besides transfer, such as important properties changed, then we changed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transferCount&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This standard is compatible with ERC-721.&lt;/p&gt;

&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;/h2&gt;

&lt;p&gt;Test cases are included in &lt;a href=&quot;/assets/eip-5008/test/test.ts&quot;&gt;test.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Run:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ../assets/eip-5008
npm &lt;span class=&quot;nb&quot;&gt;install
&lt;/span&gt;npm run &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;/h2&gt;

&lt;p&gt;See &lt;a href=&quot;/assets/eip-5008/contracts/ERC5008.sol&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC5008.sol&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;No security issues found.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Sun, 10 Apr 2022 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-5008</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-5008</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Soulbound Badge</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #5114 - Soulbound Badge&lt;/strong&gt; is in Last Call status. It is authored by Micah Zoltu (@MicahZoltu) and was originally created 2022-05-30. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-5114-soulbound-token/9417&quot;&gt;https://ethereum-magicians.org/t/eip-5114-soulbound-token/9417&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;A soulbound badge is a token that, when minted, is bound to another Non-Fungible Token (NFT), and cannot be transferred/moved after that.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/h2&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5114&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;c1&quot;&gt;// fired anytime a new instance of this badge is minted
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// this event **MUST NOT** be fired twice for the same `badgeId`
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Mint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;badgeId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nftAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nftTokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// returns the NFT that this badge is bound to.
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// this function **MUST** throw if the badge hasn&apos;t been minted yet
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// this function **MUST** always return the same result every time it is called after it has been minted
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// this function **MUST** return the same value as found in the original `Mint` event for the badge
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ownerOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;badgeId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nftAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nftTokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// returns a URI with details about this badge collection
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// the metadata returned by this is merged with the metadata return by `badgeUri(uint256)`
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// the collectionUri **MUST** be immutable (e.g., ipfs:// and not http://)
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// the collectionUri **MUST** be content addressable (e.g., ipfs:// and not http://)
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// data from `badgeUri` takes precedence over data returned by this method
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// any external links referenced by the content at `collectionUri` also **MUST** follow all of the above rules
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;collectionUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;collectionUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// returns a censorship resistant URI with details about this badge instance
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// the collectionUri **MUST** be immutable (e.g., ipfs:// and not http://)
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// the collectionUri **MUST** be content addressable (e.g., ipfs:// and not http://)
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// data from this takes precedence over data returned by `collectionUri`
&lt;/span&gt;	&lt;span class=&quot;c1&quot;&gt;// any external links referenced by the content at `badgeUri` also **MUST** follow all of the above rules
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;badgeUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;badgeId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;badgeUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

	&lt;span class=&quot;c1&quot;&gt;// returns a string that indicates the format of the `badgeUri` and `collectionUri` results (e.g., &apos;EIP-ABCD&apos; or &apos;soulbound-schema-version-4&apos;)
&lt;/span&gt;	&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;metadataFormat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Implementers of this standard &lt;strong&gt;SHOULD&lt;/strong&gt; also depend on a standard for interface detection so callers can easily find out if a given contract implements this interface.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;h3 id=&quot;immutability&quot;&gt;Immutability&lt;/h3&gt;

&lt;p&gt;By requiring that badges can never move, we both guarantee non-separability and non-mergeability among collections of soulbound badges that are bound to a single NFT while simultaneously allowing users to aggressively cache results.&lt;/p&gt;

&lt;h3 id=&quot;content-addressable-uris-required&quot;&gt;Content Addressable URIs Required&lt;/h3&gt;

&lt;p&gt;Soulbound badges are meant to be permanent badges/indicators attached to a persona.
This means that not only can the user not transfer ownership, but the minter also cannot withdraw/transfer/change ownership as well.
This includes mutating or removing any remote content as a means of censoring or manipulating specific users.&lt;/p&gt;

&lt;h3 id=&quot;no-specification-for-badgeuri-data-format&quot;&gt;No Specification for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;badgeUri&lt;/code&gt; Data Format&lt;/h3&gt;

&lt;p&gt;The format of the data pointed to by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;collectionUri()&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;badgeUri(uint256)&lt;/code&gt;, and how to merge them, is intentionally left out of this standard in favor of separate standards that can be iterated on in the future.
The immutability constraints are the only thing defined by this to ensure that the spirit of this badge is maintained, regardless of the specifics of the data format.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;metadataFormat&lt;/code&gt; function can be used to inform a caller what type/format/version of data they should expect at the URIs, so the caller can parse the data directly without first having to deduce its format via inspection.&lt;/p&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This is a new token type and is not meant to be backward compatible with any existing tokens other than existing viable souls (any asset that can be identified by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[address,id]&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;Users of badges that claim to implement this EIP must be diligent in verifying they actually do.
A badge author can create a badge that, upon initial probing of the API surface, may appear to follow the rules when in reality it doesn’t.
For example, the contract could allow transfers via some mechanism and simply not utilize them initially.&lt;/p&gt;

&lt;p&gt;It should also be made clear that soulbound badges are not bound to a human, they are bound to a persona.
A persona is any actor (which could be a group of humans) that collects multiple soulbound badges over time to build up a collection of badges.
This persona may transfer to another human, or to another group of humans, and anyone interacting with a persona should not assume that there is a single permanent human behind that persona.&lt;/p&gt;

&lt;p&gt;It is possible for a soulbound badge to be bound to another soulbound badge.
In theory, if all badges in the chain are created at the same time they could form a loop.
Software that tries to walk such a chain should take care to have an exit strategy if a loop is detected.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Mon, 30 May 2022 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-5114</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-5114</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Cross-Chain Execution</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #5164 - Cross-Chain Execution&lt;/strong&gt; is in Last Call status. It is authored by Brendan Asselstine (@asselstine), Pierrick Turelier (@PierrickGT), Chris Whinfrey (@cwhinfrey) and was originally created 2022-06-14. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-5164-cross-chain-execution/9658&quot;&gt;https://ethereum-magicians.org/t/eip-5164-cross-chain-execution/9658&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This specification defines a cross-chain execution interface for EVM-based blockchains. Implementations of this specification will allow contracts on one chain to call contracts on another by sending a cross-chain message.&lt;/p&gt;

&lt;p&gt;The specification defines two components: the “Message Dispatcher” and the “Message Executor”. The Message Dispatcher lives on the calling side, and the executor lives on the receiving side. When a message is sent, a Message Dispatcher will move the message through a transport layer to a Message Executor, where they are executed. Implementations of this specification must implement both components.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;Many Ethereum protocols need to coordinate state changes across multiple EVM-based blockchains. These chains often have native or third-party bridges that allow Ethereum contracts to execute code. However, bridges have different APIs so bridge integrations are custom. Each one affords different properties; with varying degrees of security, speed, and control. Defining a simple, common specification will increase code re-use and allow us to use common bridge implementations.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;p&gt;This specification allows contracts on one chain to send messages to contracts on another chain. There are two key interfaces that needs to be implemented:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt; lives on the origin chain and dispatches messages to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt; for execution. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt; lives on the destination chain and executes dispatched messages.&lt;/p&gt;

&lt;h3 id=&quot;messagedispatcher&quot;&gt;MessageDispatcher&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt; lives on the chain from which messages are sent. The Dispatcher’s job is to broadcast messages through a transport layer to one or more &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt; contracts.&lt;/p&gt;

&lt;p&gt;A unique &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;messageId&lt;/code&gt; MUST be generated for each message or message batch. The message identifier MUST be unique across chains and dispatchers.  This can be achieved by hashing a tuple of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chainId, dispatcherAddress, messageNonce&lt;/code&gt; where messageNonce is a monotonically increasing integer per message.&lt;/p&gt;

&lt;h4 id=&quot;messagedispatcher-methods&quot;&gt;MessageDispatcher Methods&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;dispatchMessage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Will dispatch a message to be executed by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt; on the destination chain specified by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toChainId&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt;s MUST emit the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatched&lt;/code&gt; event when a message is dispatched.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt;s MUST revert if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toChainId&lt;/code&gt; is not supported.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt;s MUST forward the message to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt; on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toChainId&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt;s MUST use a unique &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;messageId&lt;/code&gt; for each message.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt;s MUST return the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;messageId&lt;/code&gt; to allow the message sender to track the message.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt;s MAY require payment.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MessageDispatcher&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dispatchMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toChainId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;dispatchMessage&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;function&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;stateMutability&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;payable&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;toChainId&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;uint256&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;to&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;address&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;data&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bytes&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;outputs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;messageId&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bytes32&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;messagedispatcher-events&quot;&gt;MessageDispatcher Events&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;MessageDispatched&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatched&lt;/code&gt; event MUST be emitted by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt; when an individual message is dispatched.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MessageDispatcher&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MessageDispatched&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toChainId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;MessageDispatched&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;event&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;messageId&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;indexed&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bytes32&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;from&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;indexed&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;address&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;toChainId&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;indexed&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;uint256&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;to&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;address&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;data&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bytes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;messageexecutor&quot;&gt;MessageExecutor&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt; executes dispatched messages and message batches. Developers must implement a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt; in order to execute messages on the receiving chain.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt; will execute a messageId only once, but may execute messageIds in any order. This specification makes no ordering guarantees, because messages and message batches may travel non-sequentially through the transport layer.&lt;/p&gt;

&lt;h4 id=&quot;execution&quot;&gt;Execution&lt;/h4&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt;s SHOULD verify all message data with the bridge transport layer.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt;s MUST NOT successfully execute a message more than once.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt;s MUST revert the transaction when a message fails to be executed allowing the message to be retried at a later time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calldata&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt;s MUST append the ABI-packed (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;messageId&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fromChainId&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from&lt;/code&gt;) to the calldata for each message being executed. This allows the receiver of the message to verify the cross-chain sender and the chain that the message is coming from.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encodePacked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fromChainId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;calldata&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bytes&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;data&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bytes&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;messageId&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bytes32&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;fromChainId&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;uint256&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;from&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;address&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;messageexecutor-events&quot;&gt;MessageExecutor Events&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;MessageIdExecuted&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageIdExecuted&lt;/code&gt; MUST be emitted once a message or message batch has been executed.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MessageExecutor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MessageIdExecuted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fromChainId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageId&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;MessageIdExecuted&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;event&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;fromChainId&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;indexed&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;uint256&lt;/span&gt;
    &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;messageId&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;indexed&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bytes32&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;messageexecutor-errors&quot;&gt;MessageExecutor Errors&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;MessageAlreadyExecuted&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt;s MUST revert if a messageId has already been executed and SHOULD emit a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageIdAlreadyExecuted&lt;/code&gt; custom error.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MessageExecutor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MessageIdAlreadyExecuted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageId&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;MessageFailure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt;s MUST revert if an individual message fails and SHOULD emit a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageFailure&lt;/code&gt; custom error.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MessageExecutor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MessageFailure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;messageId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errorData&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageDispatcher&lt;/code&gt; can be coupled to one or more &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt;. It is up to bridges to decide how to couple the two. Users can easily bridge a message by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dispatchMessage&lt;/code&gt; without being aware of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageExecutor&lt;/code&gt; address. Messages can also be traced by a client using the data logged by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessageIdExecuted&lt;/code&gt; event.&lt;/p&gt;

&lt;p&gt;Some bridges may require payment in the native currency, so the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dispatchMessage&lt;/code&gt; function is payable.&lt;/p&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This specification is compatible with existing governance systems as it offers simple cross-chain execution.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;Bridge trust profiles are variable, so users must understand that bridge security depends on the implementation.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Tue, 14 Jun 2022 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-5164</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-5164</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>ERC-1155 Allowance Extension</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #5216 - ERC-1155 Allowance Extension&lt;/strong&gt; is in Last Call status. It is authored by Iván Mañús (@ivanmmurciaua), Juan Carlos Cantó (@EscuelaCryptoES) and was originally created 2022-07-11. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-erc1155-approval-by-amount/9898&quot;&gt;https://ethereum-magicians.org/t/eip-erc1155-approval-by-amount/9898&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This ERC defines standard functions for granular approval of &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt; tokens by both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amount&lt;/code&gt;. This ERC extends &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt;’s popularity means that multi-token management transactions occur on a daily basis. Although it can be used as a more comprehensive alternative to &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt;, ERC-1155 is most commonly used as intended: creating multiple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt;s, each with multiple tokens. While many projects interface with these semi-fungible tokens, by far the most common interactions are with NFT marketplaces.&lt;/p&gt;

&lt;p&gt;Due to the nature of the blockchain, programming errors or malicious operators can cause permanent loss of funds. It is therefore essential that transactions are as trustless as possible. ERC-1155 uses the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setApprovalForAll&lt;/code&gt; function, which approves ALL tokens with a specific &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt;. This system has obvious minimum required trust flaws. This ERC combines ideas from &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt; and &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt; in order to create a trust mechanism where an owner can allow a third party, such as a marketplace, to approve a limited (instead of unlimited) number of tokens of one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;p&gt;Contracts using this ERC MUST implement the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IERC5216&lt;/code&gt; interface.&lt;/p&gt;

&lt;h3 id=&quot;interface-implementation&quot;&gt;Interface implementation&lt;/h3&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/**
 * @title ERC-1155 Allowance Extension
 * Note: the ERC-165 identifier for this interface is 0x1be07d74
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5216&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC1155&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `id` and with an amount: `amount`.
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Approval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice Grants permission to `operator` to transfer the caller&apos;s tokens, according to `id`, and an amount: `amount`.
     * Emits an {Approval} event.
     *
     * Requirements:
     * - `operator` cannot be the caller.
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;approve&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice Returns the amount allocated to `operator` approved to transfer `account`&apos;s tokens, according to `id`.
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;approve(address operator, uint256 id, uint256 amount)&lt;/code&gt; function MUST be either &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;external&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allowance(address account, address operator, uint256 id)&lt;/code&gt; function MUST be either &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;external&lt;/code&gt; and MUST be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;view&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;safeTrasferFrom&lt;/code&gt; function (as defined by ERC-1155) MUST:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Not revert if the user has approved &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.sender&lt;/code&gt; with a sufficient &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amount&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Subtract the transferred amount of tokens from the approved amount if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.sender&lt;/code&gt; is not approved with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setApprovalForAll&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;safeBatchTransferFrom&lt;/code&gt; MUST:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add an extra condition that checks if the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allowance&lt;/code&gt; of all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ids&lt;/code&gt; have the approved &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amounts&lt;/code&gt; (See &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_checkApprovalForBatch&lt;/code&gt; function reference implementation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Approval&lt;/code&gt; event MUST be emitted when a certain number of tokens are approved.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;supportsInterface&lt;/code&gt; method MUST return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; when called with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x1be07d74&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;The name “ERC-1155 Allowance Extension” was chosen because it is a succinct description of this ERC. Users can approve their tokens by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amount&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operator&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;By having a way to approve and revoke in a manner similar to &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt;, the trust level can be more directly managed by users:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;approve&lt;/code&gt; function, users can approve an operator to spend an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amount&lt;/code&gt; of tokens for each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allowance&lt;/code&gt; function, users can see the approval that an operator has for each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt; name patterns were used due to similarities with &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt; approvals.&lt;/p&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This standard is compatible with &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;/h2&gt;

&lt;p&gt;The reference implementation can be found &lt;a href=&quot;/assets/eip-5216/ERC5216.sol&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;Users of this ERC must thoroughly consider the amount of tokens they give permission to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;operators&lt;/code&gt;, and should revoke unused authorizations.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Mon, 11 Jul 2022 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-5216</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-5216</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Endorsement - Permit for Any Functions</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #5453 - Endorsement - Permit for Any Functions&lt;/strong&gt; is in Last Call status. It is authored by Zainan Victor Zhou (@xinbenlv) and was originally created 2022-08-12. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/erc-5453-endorsement-standard/10355&quot;&gt;https://ethereum-magicians.org/t/erc-5453-endorsement-standard/10355&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This EIP establishes a general protocol for permitting and approving function calls in the same transaction relying on &lt;a href=&quot;/EIPS/eip-5750&quot;&gt;ERC-5750&lt;/a&gt;.
Unlike a few prior art (&lt;a href=&quot;/EIPS/eip-2612&quot;&gt;ERC-2612&lt;/a&gt; for &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-4494&quot;&gt;ERC-4494&lt;/a&gt; for &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt; that
usually only permit for a single behavior (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transfer&lt;/code&gt; for ERC-20 and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;safeTransferFrom&lt;/code&gt; for ERC-721) and a single approver in two transactions (first a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;permit(...)&lt;/code&gt; TX, then a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transfer&lt;/code&gt;-like TX), this EIP provides a way to permit arbitrary behaviors and aggregating multiple approvals from arbitrary number of approvers in the same transaction, allowing for Multi-Sig or Threshold Signing behavior.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Support permit(approval) alongside a function call.&lt;/li&gt;
  &lt;li&gt;Support a second approval from another user.&lt;/li&gt;
  &lt;li&gt;Support pay-for-by another user&lt;/li&gt;
  &lt;li&gt;Support multi-sig&lt;/li&gt;
  &lt;li&gt;Support persons acting in concert by endorsements&lt;/li&gt;
  &lt;li&gt;Support accumulated voting&lt;/li&gt;
  &lt;li&gt;Support off-line signatures&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;h3 id=&quot;interfaces&quot;&gt;Interfaces&lt;/h3&gt;

&lt;p&gt;The interfaces and structures referenced here are as follows&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ValidityBound&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functionParamStructHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validSince&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SingleEndorsementData&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endorserAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 32
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// dynamic = 65
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GeneralExtensionDataStruct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;erc5453MagicWord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;erc5453Type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validSince&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endorsementPayload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5453EndorsementCore&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eip5453Nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endorser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isEligibleEndorser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endorser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5453EndorsementDigest&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;computeValidityDigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_functionParamStructHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_validSince&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_validBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_nonce&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;computeFunctionParamHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_functionName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_functionParamPacked&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5453EndorsementDataTypeA&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;computeExtensionDataTypeA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validSince&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endorserAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5453EndorsementDataTypeB&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;computeExtensionDataTypeB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validSince&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endorserAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sigs&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href=&quot;/assets/eip-5453/IERC5453.sol&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IERC5453.sol&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;behavior-specification&quot;&gt;Behavior specification&lt;/h3&gt;

&lt;p&gt;As specified in &lt;a href=&quot;/EIPS/eip-5750&quot;&gt;ERC-5750 General Extensibility for Method Behaviors&lt;/a&gt;, any compliant method that has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bytes extraData&lt;/code&gt; parameter as its
last designated parameter for extending behaviors can conform to &lt;a href=&quot;/EIPS/eip-5453&quot;&gt;ERC-5453&lt;/a&gt; as the way to indicate a permit from a certain user.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Any compliant method of this EIP MUST be a &lt;a href=&quot;/EIPS/eip-5750&quot;&gt;ERC-5750&lt;/a&gt; compliant method.&lt;/li&gt;
  &lt;li&gt;Caller MUST pass in the last parameter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bytes extraData&lt;/code&gt; conforming to Solidity memory-encoded bytes of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeneralExtensionDataStruct&lt;/code&gt; specified in &lt;em&gt;Section Interfaces&lt;/em&gt;. The following descriptions are based on when decoding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bytes extraData&lt;/code&gt; into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeneralExtensionDataStruct&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;In the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeneralExtensionDataStruct&lt;/code&gt;-decoded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;extraData&lt;/code&gt;, caller MUST set the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeneralExtensionDataStruct.erc5453MagicWord&lt;/code&gt; to be the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256(&quot;ERC5453-ENDORSEMENT&quot;)&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Caller MUST set the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeneralExtensionDataStruct.erc5453Type&lt;/code&gt; to be one of the supported values.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;constant&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC5453_TYPE_A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;constant&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC5453_TYPE_B&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;When the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeneralExtensionDataStruct.erc5453Type&lt;/code&gt; is set to be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC5453_TYPE_A&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeneralExtensionDataStruct.endorsementPayload&lt;/code&gt; MUST be abi encoded bytes of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SingleEndorsementData&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;When the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeneralExtensionDataStruct.erc5453Type&lt;/code&gt; is set to be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC5453_TYPE_B&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GeneralExtensionDataStruct.endorsementPayload&lt;/code&gt; MUST be abi encoded bytes of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SingleEndorsementData[]&lt;/code&gt; (a dynamic array).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SingleEndorsementData&lt;/code&gt; MUST have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;address endorserAddress;&lt;/code&gt; and a 65-bytes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bytes sig&lt;/code&gt; signature.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bytes sig&lt;/code&gt; MUST be an ECDSA (secp256k1) signature using private key of signer whose corresponding address is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endorserAddress&lt;/code&gt; signing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validityDigest&lt;/code&gt; which is the hashTypeDataV4 of &lt;a href=&quot;/EIPS/eip-712&quot;&gt;EIP-712&lt;/a&gt; of hashStruct of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ValidityBound&lt;/code&gt; data structure as follows:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validityDigest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;eip712HashTypedDataV4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;keccak256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;keccak256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;s&quot;&gt;&quot;ValidityBound(bytes32 functionParamStructHash,uint256 validSince,uint256 validBy,uint256 nonce)&quot;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;functionParamStructHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_validSince&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_validBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_nonce&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;functionParamStructHash&lt;/code&gt; MUST be computed as follows&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;        &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functionParamStructHash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;keccak256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encodePacked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;keccak256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_functionStructure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;_functionParamPacked&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functionParamStructHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;whereas&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_functionStructure&lt;/code&gt; MUST be computed as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;function methodName(type1 param1, type2 param2, ...)&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_functionParamPacked&lt;/code&gt; MUST be computed as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enc(param1) || enco(param2) ...&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;Upon validating that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endorserAddress == ecrecover(validityDigest, signature)&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EIP1271(endorserAddress).isValidSignature(validityDigest, signature) == ERC1271.MAGICVALUE&lt;/code&gt;, the single endorsement MUST be deemed valid.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Compliant method MAY choose to impose a threshold for a number of endorsements needs to be valid in the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC5453_TYPE_B&lt;/code&gt; kind of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;endorsementPayload&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validSince&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validBy&lt;/code&gt; are both inclusive. Implementer MAY choose to use blocknumber or timestamp. Implementors SHOULD find a way to indicate whether &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validSince&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validBy&lt;/code&gt; is blocknumber or timestamp.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;We chose to have both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC5453_TYPE_A&lt;/code&gt;(single-endorsement) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC5453_TYPE_B&lt;/code&gt;(multiple-endorsements, same nonce for entire contract) so we
could balance a wider range of use cases. E.g. the same use cases of ERC-2612 and &lt;a href=&quot;/EIPS/eip-4494&quot;&gt;ERC-4494&lt;/a&gt; can be supported by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC5453_TYPE_A&lt;/code&gt;. And threshold approvals can be done via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC5453_TYPE_B&lt;/code&gt;. More complicated approval types can also be extended by defining new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC5453_TYPE_?&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We chose to include both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validSince&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validBy&lt;/code&gt; to allow maximum flexibility in expiration. This can also be supported natively by the EVM if &lt;a href=&quot;/EIPS/eip-5081&quot;&gt;ERC-5081&lt;/a&gt; is adopted, but &lt;a href=&quot;/EIPS/eip-5081&quot;&gt;ERC-5081&lt;/a&gt; will not be adopted anytime soon, so we choose to add these two numbers in our protocol to allow
smart contract level support.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;The design assumes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bytes calldata extraData&lt;/code&gt; to maximize the flexibility of future extensions. This assumption is compatible with &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt; and many other ERC-track EIPs. Those that aren’t, such as &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt;, can also be updated to support it, such as using a wrapper contract or proxy upgrade.&lt;/p&gt;

&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;/h2&gt;

&lt;p&gt;In addition to the specified algorithm for validating endorser signatures, we also present the following reference implementations.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;@openzeppelin/contracts/utils/cryptography/EIP712.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;./IERC5453.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AERC5453Endorsible&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EIP712&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;IERC5453EndorsementCore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5453EndorsementDigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5453EndorsementDataTypeA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5453EndorsementDataTypeB&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_validate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msgDigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SingleEndorsementData&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endersement&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;endersement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;AERC5453Endorsible: wrong signature length&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;SignatureChecker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isValidSignatureNow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;endersement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endorserAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;msgDigest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;endersement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sig&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;AERC5453Endorsible: invalid signature&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ...
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;modifier&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyEndorsed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_functionParamStructHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_extensionData&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_isEndorsed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_functionParamStructHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_extensionData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;computeExtensionDataTypeB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validSince&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endorserAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sigs&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;pure&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endorserAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sigs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;SingleEndorsementData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endorsements&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SingleEndorsementData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[](&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;endorserAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endorserAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;endorsements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SingleEndorsementData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;endorserAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;sigs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;GeneralExtensionDataStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;MAGIC_WORLD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;ERC5453_TYPE_B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;nonce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;validSince&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;validBy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endorsements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href=&quot;/assets/eip-5453/AERC5453.sol&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AERC5453.sol&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;reference-implementation-of-endorsableerc721&quot;&gt;Reference Implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EndorsableERC721&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Here is a reference implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EndorsableERC721&lt;/code&gt; that achieves similar behavior to &lt;a href=&quot;/EIPS/eip-4494&quot;&gt;ERC-4494&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EndorsableERC721&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC721&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AERC5453Endorsible&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//...
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_extraData&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;onlyEndorsed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_computeFunctionParamHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;function mint(address _to,uint256 _tokenId)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_extraData&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_mint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href=&quot;/assets/eip-5453/EndorsableERC721.sol&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EndorsableERC721.sol&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;reference-implementation-of-thresholdmultisigforwarder&quot;&gt;Reference Implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ThresholdMultiSigForwarder&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Here is a reference implementation of ThresholdMultiSigForwarder that achieves similar behavior of multi-sig threshold approval
remote contract call like a Gnosis-Safe wallet.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ThresholdMultiSigForwarder&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AERC5453Endorsible&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//...
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_dest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_gasLimit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_calldata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_extraData&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;onlyEndorsed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_computeFunctionParamHash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;function forward(address _dest,uint256 _value,uint256 _gasLimit,bytes calldata _calldata)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_dest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_gasLimit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;keccak256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_calldata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_extraData&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errorMessage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Fail to call remote contract&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returndata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_dest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_calldata&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;verifyCallResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returndata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errorMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href=&quot;/assets/eip-5453/ThresholdMultiSigForwarder.sol&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ThresholdMultiSigForwarder.sol&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;h3 id=&quot;replay-attacks&quot;&gt;Replay Attacks&lt;/h3&gt;

&lt;p&gt;A replay attack is a type of attack on cryptography authentication. In a narrow sense, it usually refers to a type of attack that circumvents the cryptographically signature verification by reusing an existing signature for a message being signed again. Any implementations relying on this EIP must realize that all smart endorsements described here are cryptographic signatures that are &lt;em&gt;public&lt;/em&gt; and can be obtained by anyone. They must foresee the possibility of a replay of the transactions not only at the exact deployment of the same smart contract, but also other deployments of similar smart contracts, or of a version of the same contract on another &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chainId&lt;/code&gt;, or any other similar attack surfaces. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nonce&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validSince&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;validBy&lt;/code&gt; fields are meant to restrict the surface of attack but might not fully eliminate the risk of all such attacks, e.g. see the &lt;a href=&quot;#phishing&quot;&gt;Phishing&lt;/a&gt; section.&lt;/p&gt;

&lt;h3 id=&quot;phishing&quot;&gt;Phishing&lt;/h3&gt;

&lt;p&gt;It’s worth pointing out a special form of replay attack by phishing. An adversary can design another smart contract in a way that the user may be tricked into signing a smart endorsement for a seemingly legitimate purpose, but the data-to-designed matches the target application&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Fri, 12 Aug 2022 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-5453</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-5453</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Multi-privilege Management NFT Extension</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #5496 - Multi-privilege Management NFT Extension&lt;/strong&gt; is in Last Call status. It is authored by Jeremy Z (@wnft) and was originally created 2022-07-30. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-5496-multi-privilege-management-extension-for-erc-721/10427&quot;&gt;https://ethereum-magicians.org/t/eip-5496-multi-privilege-management-extension-for-erc-721/10427&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This EIP defines an interface extending &lt;a href=&quot;/EIPS/eip-721&quot;&gt;EIP-721&lt;/a&gt; to provide shareable multi-privileges for NFTs. Privileges may be on-chain (voting rights, permission to claim an airdrop) or off-chain (a coupon for an online store, a discount at a local restaurant, access to VIP lounges in airports). Each NFT may contain many privileges, and the holder of a privilege can verifiably transfer that privilege to others. Privileges may be non-shareable or shareable. Shareable privileges can be cloned, with the provider able to adjust the details according to the spreading path. Expiration periods can also be set for each privilege.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;This standard aims to efficiently manage privileges attached to NFTs in real-time. Many NFTs have functions other than just being used as profile pictures or art collections, they may have real utilities in different scenarios. For example, a fashion store may give a discount for its own NFT holders; a DAO member NFT holder can vote for the proposal of how to use their treasury; a dApp may create an airdrop event to attract a certain group of people like some blue chip NFT holders to claim; the grocery store can issue its membership card on chain (as an NFT) and give certain privileges when the members shop at grocery stores, etc. There are cases when people who own NFTs do not necessarily want to use their privileges. By providing additional data recording different privileges a NFT collection has and interfaces to manage them, users can transfer or sell privileges without losing their ownership of the NFT.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/EIPS/eip-721&quot;&gt;EIP-721&lt;/a&gt; only records the ownership and its transfer, the privileges of an NFT are not recorded on-chain. This extension would allow merchants/projects to give out a certain privilege to a specified group of people, and owners of the privileges can manage each one of the privileges independently. This facilitates a great possibility for NFTs to have real usefulness.&lt;/p&gt;

&lt;p&gt;For example, an airline company issues a series of &lt;a href=&quot;/EIPS/eip-721&quot;&gt;EIP-721&lt;/a&gt;/&lt;a href=&quot;/EIPS/eip-1155&quot;&gt;EIP-1155&lt;/a&gt; tokens to Crypto Punk holders to give them privileges, in order to attract them to join their club. However, since these tokens are not bound to the original NFT, if the original NFT is transferred, these privileges remain in the hands of the original holders, and the new holders cannot enjoy the privileges automatically.
So, we propose a set of interfaces that can bind the privileges to the underlying NFT, while allowing users to manage the privileges independently.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;p&gt;Every contract complying with this standard MUST implement the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IERC5496&lt;/code&gt; interface. The &lt;strong&gt;shareable multi-privilege extension&lt;/strong&gt; is OPTIONAL for EIP-721 contracts.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;/// @title multi-privilege extension for EIP-721
///  Note: the EIP-165 identifier for this interface is 0x076e1bbb
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5496&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// @notice Emitted when `owner` changes the `privilege holder` of a NFT.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrivilegeAssigned&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expires&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// @notice Emitted when `contract owner` changes the `total privilege` of the collection
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrivilegeTotalChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;oldTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice set the privilege holder of a NFT.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev expires should be less than 30 days
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// Throws if `msg.sender` is not approved or owner of the tokenId.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The NFT to set privilege for
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param privilegeId The privilege to set
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param user The privilege holder to set
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param expires For how long the privilege holder can have
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setPrivilege&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expires&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Return the expiry timestamp of a privilege
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The identifier of the queried NFT
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param privilegeId The identifier of the queried privilege
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return Whether a user has a certain privilege
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeExpires&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Check if a user has a certain privilege
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The identifier of the queried NFT
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param privilegeId The identifier of the queried privilege
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param user The address of the queried user
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return Whether a user has a certain privilege
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasPrivilege&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Every contract implementing this standard SHOULD set a maximum privilege number before setting any privilege, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;privilegeId&lt;/code&gt; MUST NOT be greater than the maximum privilege number.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PrivilegeAssigned&lt;/code&gt; event MUST be emitted when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setPrivilege&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PrivilegeTotalChanged&lt;/code&gt; event MUST be emitted when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;total privilege&lt;/code&gt; of the collection is changed.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;supportsInterface&lt;/code&gt; method MUST return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; when called with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x076e1bbb&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;/// @title Cloneable extension - Optional for EIP-721
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC721Cloneable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// @notice Emitted when set the `privilege ` of a NFT cloneable.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrivilegeCloned&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice set a certain privilege cloneable
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The identifier of the queried NFT
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param privilegeId The identifier of the queried privilege
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param referrer The address of the referrer
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return Whether the operation is successful or not
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clonePrivilege&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;referrer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PrivilegeCloned&lt;/code&gt; event MUST be emitted when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clonePrivilege&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;For Compliant contract, it is RECOMMENDED to use &lt;a href=&quot;/EIPS/eip-1271&quot;&gt;EIP-1271&lt;/a&gt; to validate the signatures.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;h3 id=&quot;shareable-privileges&quot;&gt;Shareable Privileges&lt;/h3&gt;

&lt;p&gt;The number of privilege holders is limited by the number of NFTs if privileges are non-shareable. A shareable privilege means the original privilege holder can copy the privilege and give it to others, not transferring his/her own privilege to them. This mechanism greatly enhances the spread of privileges as well as the adoption of NFTs.&lt;/p&gt;

&lt;h3 id=&quot;expire-date-type&quot;&gt;Expire Date Type&lt;/h3&gt;

&lt;p&gt;The expiry timestamp of a privilege is a timestamp and stored in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint256&lt;/code&gt; typed variables.&lt;/p&gt;

&lt;h3 id=&quot;beneficiary-of-referrer&quot;&gt;Beneficiary of Referrer&lt;/h3&gt;

&lt;p&gt;For example, a local pizza shop offers a 30% off Coupon and the owner of the shop encourages their consumers to share the coupon with friends, then the friends can get the coupon. Let’s say Tom gets 30% off Coupon from the shop and he shares the coupon with Alice. Alice gets the coupon too and Alice’s referrer is Tom. For some certain cases, Tom may get more rewards from the shop. This will help the merchants in spreading the promotion among consumers.&lt;/p&gt;

&lt;h3 id=&quot;proposal-nft-transfer&quot;&gt;Proposal: NFT Transfer&lt;/h3&gt;

&lt;p&gt;If the owner of the NFT transfers ownership to another user, there is no impact on “privileges”. But errors may occur if the owner tries to withdraw the original &lt;a href=&quot;/EIPS/eip-721&quot;&gt;EIP-721&lt;/a&gt; token from the wrapped NFT through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unwrap()&lt;/code&gt; if any available privileges are still ongoing. We protect the rights of holders of the privileges to check the last expiration date of the privilege.&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getBlockTimestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastExpiresAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;privilege not yet expired&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ownerOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;not owner&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;_burn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;IERC721&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transferFrom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Unwrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This EIP is compatible with any kind of NFTs that follow the EIP-721 standard. It only adds more functions and data structures without interfering with the original &lt;a href=&quot;/EIPS/eip-721&quot;&gt;EIP-721&lt;/a&gt; standard.&lt;/p&gt;

&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;/h2&gt;

&lt;p&gt;Test cases are implemented with the reference implementation.&lt;/p&gt;

&lt;h3 id=&quot;test-code&quot;&gt;Test Code&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;/assets/eip-5496/test/test.js&quot;&gt;test.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run in terminal:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;truffle &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; ./test/test.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;/assets/eip-5496/test/testCloneable.js&quot;&gt;testCloneable.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run in terminal:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;truffle &lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; ./test/testCloneable.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;/h2&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// SPDX-License-Identifier: CC0-1.0
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;@openzeppelin/contracts/token/ERC721/ERC721.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;@openzeppelin/contracts/utils/introspection/IERC165.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;./IERC5496.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC5496&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC721&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC5496&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrivilegeRecord&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expiresAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrivilegeStorage&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lastExpiresAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// privId =&amp;gt; PrivilegeRecord
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrivilegeRecord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// tokenId =&amp;gt; PrivilegeStorage
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrivilegeStorage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeDelegator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbol_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ERC721&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;symbol_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setPrivilege&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expires&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hasPrivilege&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ownerOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_isApprovedOrOwner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_isDelegatorOrHolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ERC721: transfer caller is not owner nor approved&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expires&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timestamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;days&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;expire time invalid&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;invalid privilege id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_isApprovedOrOwner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expiresAt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expires&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastExpiresAt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expires&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastExpiresAt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expires&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrivilegeAssigned&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expiresAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasPrivilege&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expiresAt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ownerOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeExpires&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expiresAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_setPrivilegeTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrivilegeTotalChanged&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;total&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeTotal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;privilegeTotal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getPrivilegeInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expiresAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expiresAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setDelegator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delegator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;privilegeDelegator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delegator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_isDelegatorOrHolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delegator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;holder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeBook&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privilegeEntry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;privId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
         &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delegator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;holder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isApprovedForAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;holder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delegator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privilegeDelegator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;holder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delegator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;supportsInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes4&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interfaceId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interfaceId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IERC5496&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interfaceId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;supportsInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interfaceId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;Implementations must thoroughly consider who has the permission to set or clone privileges.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Sat, 30 Jul 2022 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-5496</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-5496</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Contracts Dependencies Registry</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #6224 - Contracts Dependencies Registry&lt;/strong&gt; is in Last Call status. It is authored by Artem Chystiakov (@arvolear) and was originally created 2022-12-27. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-6224-contracts-dependencies-registry/12316&quot;&gt;https://ethereum-magicians.org/t/eip-6224-contracts-dependencies-registry/12316&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This EIP introduces an on-chain registry system that a decentralized protocol may use to manage its smart contracts.&lt;/p&gt;

&lt;p&gt;The proposed system consists of two components: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dependant&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; contract stores references to every smart contract used within a protocol, optionally making them upgradeable by deploying self-managed proxies on top, and acts as a hub the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dependant&lt;/code&gt; contracts query to fetch their required dependencies from.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;In the ever-growing Ethereum ecosystem, projects tend to become more and more complex. Modern protocols require portability and agility to satisfy customer needs by continuously delivering new features and staying on pace with the industry. However, the requirement is hard to achieve due to the immutable nature of blockchains and smart contracts. Moreover, the increased complexity and continuous delivery bring bugs and entangle the dependencies between the contracts, making systems less supportable.&lt;/p&gt;

&lt;p&gt;Applications that have a clear architectural facade; which are designed with forward compatibility in mind; which dependencies are transparent and clean are easier to develop and maintain. The given EIP tries to solve the aforementioned problems by presenting two smart contracts: the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dependant&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The advantages of using the provided system might be:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Structured smart contracts management via specialized contracts.&lt;/li&gt;
  &lt;li&gt;Ad-hoc upgradeability provision of a protocol.&lt;/li&gt;
  &lt;li&gt;Runtime addition, removal, and substitution of smart contracts.&lt;/li&gt;
  &lt;li&gt;Dependency injection mechanism to keep smart contracts’ dependencies under control.&lt;/li&gt;
  &lt;li&gt;Ability to specify custom access control rules to maintain the protocol.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;/h3&gt;

&lt;p&gt;The system consists of two smart contracts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; that is a singleton registry to manage and upgrade a protocol’s smart contracts.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dependant&lt;/code&gt; that is a mix-in which enables a dependency injection mechanism.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following diagram depicts the relationship between the registry and its dependants:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/eip-6224/diagram.svg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;contractsregistry&quot;&gt;ContractsRegistry&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; is the main contract of the proposed system. It MUST store the references to every standalone contract used within a protocol. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractRegistry&lt;/code&gt; MAY be configured to deploy a proxy contract of choice on top of the registered contracts.&lt;/p&gt;

&lt;p&gt;Additionally, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; MUST reject the registration of zero addresses.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; MUST implement the following interface:&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IContractsRegistry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The event that is emitted when the contract gets added to the registry
     * @param name the name of the contract
     * @param contractAddress the address of the added contract
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ContractAdded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The event that is emitted when the proxy contract gets added to the registry
     * @param name the name of the contract
     * @param contractAddress the address of the proxy contract
     * @param implementation the address of the implementation contract
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProxyContractAdded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;implementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The event that is emitted when the proxy contract gets upgraded through the registry
     * @param name the name of the contract
     * @param newImplementation the address of the new implementation contract
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProxyContractUpgraded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The event that is emitted when the contract gets removed from the registry
     * @param name the name of the removed contract
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ContractRemoved&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that returns an associated contract by the name. 
     *
     * MUST revert if the requested contract is `address(0)`
     *
     * @param name the name of the contract
     * @return the address of the contract
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that checks if a contract with a given name has been added
     * @param name the name of the contract
     * @return true if the contract is present in the registry
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that injects dependencies into the given contract.
     *
     * MUST call the `setDependencies()` with `address(this)` and `bytes(&quot;&quot;)` as arguments on the provided contract
     *
     * @param name the name of the contract
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injectDependencies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that injects dependencies into the given contract with extra data.
     *
     * MUST call the `setDependencies()` with `address(this)` and `data` as arguments on the provided contract
     *
     * @param name the name of the contract
     * @param data the extra context data that will be passed to the dependant contract
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injectDependenciesWithData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that upgrades added proxy contract with a new implementation.
     *
     * It is the Owner&apos;s responsibility to ensure the compatibility between implementations.
     *
     * MUST emit `ProxyContractUpgraded` event
     *
     * @param name the name of the proxy contract
     * @param newImplementation the new implementation the proxy will be upgraded to
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upgradeContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that upgrades added proxy contract with a new implementation, providing data
     *
     * It is the Owner&apos;s responsibility to ensure the compatibility between implementations.
     *
     * MUST emit `ProxyContractUpgraded` event
     *
     * @param name the name of the proxy contract
     * @param newImplementation the new implementation the proxy will be upgraded to
     * @param data the data that the proxy will be called with after upgrade. This can be an ABI encoded function call
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upgradeContractAndCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that adds pure (non-proxy) contracts to the `ContractsRegistry`. The contracts MAY either be
     * the ones the system does not have direct upgradeability control over or those that are not upgradeable by design.
     *
     * MUST emit `ContractAdded` event. Reverts if the provided address is `address(0)`
     *
     * @param name the name to associate the contract with
     * @param contractAddress the address of the contract to be added
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that adds the proxy contracts to the registry by deploying them above the provided implementation.
     *
     * The function may be used to add a contract that the `ContractsRegistry` has to be able to upgrade.
     *
     * MUST emit `ProxyContractAdded` event. Reverts if implementation address is `address(0)`
     *
     * @param name the name to associate the contract with
     * @param contractAddress the address of the implementation to point the proxy to
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addProxyContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that adds the proxy contracts to the registry by deploying them above the provided implementation,
     * providing data.
     *
     * The function may be used to add a contract that the `ContractsRegistry` has to be able to upgrade.
     *
     * MUST emit `ProxyContractAdded` event. Reverts if implementation address is `address(0)`
     *
     * @param name the name to associate the contract with
     * @param contractAddress the address of the implementation
     * @param data the data that the proxy will be called with. This can be an ABI encoded initialization call
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addProxyContractAndCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that adds an already deployed proxy to the `ContractsRegistry`. It MAY be used
     * when the system migrates to the new `ContractRegistry`. In that case, the new registry MUST have the
     * credentials to upgrade the newly added proxies.
     *
     * MUST emit `ProxyContractAdded` event. Reverts if implementation address is `address(0)`
     *
     * @param name the name to associate the contract with
     * @param contractAddress the address of the proxy
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;justAddProxyContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function to remove contracts from the ContractsRegistry.
     *
     * MUST emit `ContractRemoved` event. Reverts if the contract is already removed
     *
     * @param name the associated name with the contract
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;removeContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dependant&quot;&gt;Dependant&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; works together with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dependant&lt;/code&gt; contract. Every standalone contract of a protocol MUST inherit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dependant&lt;/code&gt; in order to support the dependency injection mechanism.&lt;/p&gt;

&lt;p&gt;The required dependencies MUST be set in the overridden &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setDependencies&lt;/code&gt; method, not in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;constructor&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initializer&lt;/code&gt; methods.&lt;/p&gt;

&lt;p&gt;Only the injector MUST be able to call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setDependencies&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setInjector&lt;/code&gt; methods. The initial injector will be a zero address, in that case, the call MUST NOT revert on access control checks.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dependant&lt;/code&gt; contract MUST implement the following interface:&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDependant&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that is called from the `ContractsRegistry` to inject dependencies.
     *
     * The contract MUST perform a proper access check of `msg.sender`. The calls should only be possible from `ContractsRegistry`
     *
     * @param contractsRegistry the registry to pull dependencies from
     * @param data the extra data that might provide additional application-specific context
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setDependencies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractsRegistry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that sets the new dependency injector.
     *
     * The contract MUST perform a proper access check of `msg.sender`
     *
     * @param injector the new dependency injector
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice The function that gets the current dependency injector
     * @return the current dependency injector
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dependant&lt;/code&gt; contract MAY store the dependency injector (usually &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt;) address in the special slot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x3d1f25f1ac447e55e7fec744471c4dab1c6a2b6ffb897825f9ea3d2e8c9be583&lt;/code&gt; (obtained as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bytes32(uint256(keccak256(&quot;eip6224.dependant.slot&quot;)) - 1)&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;There are a few design decisions that have to be explicitly specified:&lt;/p&gt;

&lt;h3 id=&quot;contractsregistry-rationale&quot;&gt;ContractsRegistry Rationale&lt;/h3&gt;

&lt;h4 id=&quot;contracts-identifier&quot;&gt;Contracts Identifier&lt;/h4&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; contracts identifier is chosen over the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uint256&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bytes32&lt;/code&gt; to maintain code readability and reduce the human error chances when interacting with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt;. Being the topmost smart contract of a protocol, it MAY be typical for the users to interact with it via block explorers or DAOs. Clarity was prioritized over gas usage.&lt;/p&gt;

&lt;p&gt;Due to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string&lt;/code&gt; identifier, the event parameters are not indexed. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string indexed&lt;/code&gt; parameter will become the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keccak256&lt;/code&gt; hash of the contract name if it is larger than 32 bytes. This fact reduces readability, which was prioritized.&lt;/p&gt;

&lt;h4 id=&quot;reverts&quot;&gt;Reverts&lt;/h4&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getContract&lt;/code&gt; view function reverts if the requested contract is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;address(0)&lt;/code&gt;. This is essential to minimize the risks of misinitialization of a protocol. Correct contracts SHOULD be added to the registry prior to any dependency injection actions.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addContract&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addProxyContract&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addProxyContractAndCall&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;justAddProxyContract&lt;/code&gt; methods revert if the provided address is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;address(0)&lt;/code&gt; for the same risk minimization reason.&lt;/p&gt;

&lt;h3 id=&quot;dependant-rationale&quot;&gt;Dependant Rationale&lt;/h3&gt;

&lt;h4 id=&quot;dependencies&quot;&gt;Dependencies&lt;/h4&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; parameter is provided to carry additional application-specific context. It MAY be used to extend the method’s behavior.&lt;/p&gt;

&lt;h4 id=&quot;injector&quot;&gt;Injector&lt;/h4&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setInjector&lt;/code&gt; function is made &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;external&lt;/code&gt; to support the dependency injection mechanism for factory-made contracts. However, the method SHOULD be used with extra care.&lt;/p&gt;

&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note that the reference implementation depends on OpenZeppelin contracts &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.9.2&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;contractsregistry-implementation&quot;&gt;ContractsRegistry Implementation&lt;/h3&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;@openzeppelin/contracts/utils/Address.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TransparentUpgradeableProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OwnableUpgradeable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dependant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;./Dependant.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IContractsRegistry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ContractAdded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProxyContractAdded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;implementation&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProxyContractUpgraded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ContractRemoved&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injectDependencies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injectDependenciesWithData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upgradeContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upgradeContractAndCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addProxyContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addProxyContractAndCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;justAddProxyContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;removeContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProxyUpgrader&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;immutable&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_OWNER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;modifier&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_onlyOwner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_OWNER&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upgrade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;what_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;TransparentUpgradeableProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;payable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;what_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upgradeToAndCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;TransparentUpgradeableProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;payable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;what_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upgradeTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getImplementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;what_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// bytes4(keccak256(&quot;implementation()&quot;)) == 0x5c60da1b
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returndata_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;what_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;staticcall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;hex&quot;5c60da1b&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;success_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ProxyUpgrader: not a proxy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;abi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;returndata_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_onlyOwner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_OWNER&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ProxyUpgrader: not an owner&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ContractsRegistry&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IContractsRegistry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OwnableUpgradeable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ProxyUpgrader&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_proxyUpgrader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_contracts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_isProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__ContractsRegistry_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initializer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_proxyUpgrader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProxyUpgrader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;__Ownable_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_contracts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;ContractsRegistry: this mapping doesn&apos;t exist&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hasContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_contracts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getProxyUpgrader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_proxyUpgrader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injectDependencies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;injectDependenciesWithData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injectDependenciesWithData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_contracts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;ContractsRegistry: this mapping doesn&apos;t exist&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;Dependant&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependant_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dependant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;dependant_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setDependencies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upgradeContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;upgradeContractAndCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upgradeContractAndCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractToUpgrade_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_contracts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;contractToUpgrade_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;ContractsRegistry: this mapping doesn&apos;t exist&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_isProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contractToUpgrade_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;ContractsRegistry: not a proxy contract&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;_proxyUpgrader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upgrade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contractToUpgrade_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProxyContractUpgraded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newImplementation_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;ContractsRegistry: zero address is forbidden&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;_contracts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ContractAdded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addProxyContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;addProxyContractAndCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;addProxyContractAndCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;ContractsRegistry: zero address is forbidden&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proxyAddr_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_deployProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_proxyUpgrader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;_contracts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proxyAddr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_isProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;proxyAddr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProxyContractAdded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proxyAddr_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;justAddProxyContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;ContractsRegistry: zero address is forbidden&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;_contracts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_isProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ProxyContractAdded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_proxyUpgrader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getImplementation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;removeContract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_contracts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&quot;ContractsRegistry: this mapping doesn&apos;t exist&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_isProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_contracts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ContractRemoved&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_deployProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;admin_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TransparentUpgradeableProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contractAddress_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;admin_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;dependant-implementation&quot;&gt;Dependant Implementation&lt;/h3&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDependant&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setDependencies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractsRegistry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dependant&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IDependant&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/**
     * @dev bytes32(uint256(keccak256(&quot;eip6224.dependant.slot&quot;)) - 1)
     */&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;constant&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_INJECTOR_SLOT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;mh&quot;&gt;0x3d1f25f1ac447e55e7fec744471c4dab1c6a2b6ffb897825f9ea3d2e8c9be583&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;modifier&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dependant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_checkInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_setInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setDependencies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contractsRegistry_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injector_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_checkInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_setInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;injector_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injector_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;slot_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_INJECTOR_SLOT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;assembly&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;injector_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slot_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_setInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injector_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;slot_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_INJECTOR_SLOT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;assembly&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sstore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slot_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injector_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_checkInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injector_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getInjector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;injector_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;injector_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Dependant: not an injector&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;It is crucial for the owner of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; to keep their keys in a safe place. The loss/leakage of credentials to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; will lead to the application’s point of no return. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractRegistry&lt;/code&gt; is a cornerstone of a protocol, access must be granted to the trusted parties only.&lt;/p&gt;

&lt;h3 id=&quot;contractsregistry-security&quot;&gt;ContractsRegistry Security&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ContractsRegistry&lt;/code&gt; does not perform any upgradeability checks between the proxy upgrades. It is the user’s responsibility to make sure that the new implementation is compatible with the old one.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;dependant-security&quot;&gt;Dependant Security&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dependant&lt;/code&gt; contract MUST set its dependency injector no later than the first call to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setDependencies&lt;/code&gt; function is made. That being said, it is possible to front-run the first dependency injection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Tue, 27 Dec 2022 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-6224</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-6224</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Single-contract Multi-delegatecall</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #6357 - Single-contract Multi-delegatecall&lt;/strong&gt; is in Last Call status. It is authored by Gavin John (@Pandapip1) and was originally created 2023-01-18. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-6357-single-contract-multicall/12621&quot;&gt;https://ethereum-magicians.org/t/eip-6357-single-contract-multicall/12621&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This EIP standardizes an interface containing a single function, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;multicall&lt;/code&gt;, allowing EOAs to call multiple functions of a smart contract in a single transaction, and revert all calls if any call fails.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;Currently, in order to transfer several &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt; NFTs, one needs to submit a number of transactions equal to the number of NFTs being tranferred. This wastes users’ funds by requiring them to pay 21000 gas fee for every NFT they transfer.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;p&gt;Contracts implementing this EIP must implement the following interface:&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMulticall&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// @notice           Takes an array of abi-encoded call data, delegatecalls itself with each calldata, and returns the abi-encoded result
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev              Reverts if any delegatecall reverts
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param    data    The abi-encoded data
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @returns  results The abi-encoded return values
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;multicall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice           OPTIONAL. Takes an array of abi-encoded call data, delegatecalls itself with each calldata, and returns the abi-encoded result
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev              Reverts if any delegatecall reverts
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param    data    The abi-encoded data
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param    values  The effective msg.values. These must add up to at most msg.value
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @returns  results The abi-encoded return values
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;multicallPayable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;payable&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;multicallPayable&lt;/code&gt; is optional because it isn’t always feasible to implement, due to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.value&lt;/code&gt; splitting.&lt;/p&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This is compatible with most existing multicall functions.&lt;/p&gt;

&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;/h2&gt;

&lt;p&gt;The following JavaScript code, using the Ethers library, should atomically transfer &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amt&lt;/code&gt; units of an &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt; token to both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addressA&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addressB&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;multicall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;encodeFunctionData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;transfer&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addressA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;amt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;encodeFunctionData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;transfer&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addressB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;amt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;/h2&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;/// Derived from OpenZeppelin&apos;s implementation
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Multicall&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IMulticall&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;multicall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returndata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;delegatecall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;returndata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;multicallPayable&lt;/code&gt; should only be used if the contract is able to support it. A naive attempt at implementing it could allow an attacker to call a payable function multiple times with the same ether.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Wed, 18 Jan 2023 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-6357</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-6357</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Empty accounts deprecation</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #7523 - Empty accounts deprecation&lt;/strong&gt; is in Last Call status. It is authored by Peter Davies (@petertdavies) and was originally created 2023-09-19. It is in the Core category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-7523-empty-accounts-deprecation/15870&quot;&gt;https://ethereum-magicians.org/t/eip-7523-empty-accounts-deprecation/15870&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This EIP prohibits the state of any post-merge network from containing empty accounts. Since no empty accounts exist outside the testsuite and no new ones can be created this requirement is already achieved in practice. An explicit ban reduces technical debt going forward.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;The possibility of empty accounts is a historical artifact of the early history of Ethereum. The only networks that have ever been capable of containing them are Ethereum Mainnet, the deprecated testnet Ropsten, Etheruem Classic Mainnet and various Ethereum Classic testnets. All remaining empty accounts on Mainnet were cleared in block &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;14049881&lt;/code&gt; (transaction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xf955834bfa097458a9cf6b719705a443d32e7f43f20b9b0294098c205b4bcc3d&lt;/code&gt;) and a similar transaction was sent on Ethereum Classic. None of the other myriad EVM-compatible networks are old enough to have empty accounts and there is no realistic prospect that anyone will encounter an empty account in a production context.&lt;/p&gt;

&lt;p&gt;Despite empty accounts no longer existing, they still impose a legacy of technical debt. &lt;a href=&quot;/EIPS/eip-161&quot;&gt;EIP-161&lt;/a&gt; imposes complicated rules that require a client to delete an empty account when it is “touched”. As the Ethereum specification continues to evolve new edgecases of the “touch” rules arise which must be debated, implemented, tested and documented. If a future client wishes to only support post-merge blocks it must implement unnecessary empty account support solely to pass the test suite.&lt;/p&gt;

&lt;p&gt;By prohibiting empty accounts on post-merge networks, this EIP frees designers and implementers of Ethereum and related blockchains from the burden of having to consider them going forward.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;p&gt;An empty account is an account with has &lt;strong&gt;no code&lt;/strong&gt; and &lt;strong&gt;zero nonce&lt;/strong&gt; and &lt;strong&gt;zero balance&lt;/strong&gt;. This is the same as the definition in &lt;a href=&quot;/EIPS/eip-161&quot;&gt;EIP-161&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On networks that undergo the merge transition, the pre state of the merge block may not contain any empty accounts. For networks that are merged at genesis, none of the genesis accounts may be empty accounts.&lt;/p&gt;

&lt;p&gt;Rather than performing a scan of the state, clients MAY assume the following chains have no post-merge empty accounts:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;The Mainnet chain whose merge block has hash &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x56a9bb0302da44b8c0b3df540781424684c3af04d0b7a38d72842b762076a664&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Any chain which satisfies all of the following:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;has no empty accounts in the genesis.&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;had a post Spurious Dragon fork at genesis.&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Ethereum specification is declared to be undefined in the presence of an empty account in a post-merge context. Any testcase involving post-merge empty accounts is invalid.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;This EIP was drafted to be the simplest possible way of eliminating the long term technical debt imposed by empty accounts. The Merge was chosen as a natural easily identifiable cutoff point.&lt;/p&gt;

&lt;p&gt;Alternative approaches include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Using an earlier cutoff point, such as block &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;14049881&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Identifying a wider range of edge case behaviour that never happened.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These approaches were rejected as being unnecessarily complicated.&lt;/p&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;As EIP does not change any behaviour that can occur outside the testsuite, it has no backwards compatibility consequences.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;The validity of this EIP is dependent on the assertion that all empty accounts on Ethereum Mainnet were cleared prior to the merge. This should be subject to appropriate verification.&lt;/p&gt;

&lt;p&gt;Any networks artificially created with empty accounts will cause problems with tooling and clients.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Tue, 19 Sep 2023 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-7523</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-7523</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Revert creation in case of non-empty storage</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #7610 - Revert creation in case of non-empty storage&lt;/strong&gt; is in Last Call status. It is authored by Gary Rong (@rjl493456442), Martin Holst Swende (@holiman) and was originally created 2024-02-02. It is in the Core category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-revert-creation-in-case-of-non-empty-storage/18452&quot;&gt;https://ethereum-magicians.org/t/eip-revert-creation-in-case-of-non-empty-storage/18452&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This EIP causes contract creation to throw an error when attempted at an address with pre-existing storage.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;p&gt;If a contract creation is attempted due to a creation transaction, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CREATE&lt;/code&gt; opcode, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CREATE2&lt;/code&gt; opcode, or any other reason, and the destination address already has either a nonzero nonce, a nonzero code length, or non-empty storage, 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;/p&gt;

&lt;p&gt;This EIP amends &lt;a href=&quot;/EIPS/eip-684&quot;&gt;EIP-684&lt;/a&gt; with one extra condition, requiring empty storage for contract deployment.&lt;/p&gt;

&lt;p&gt;This EIP will not affect &lt;a href=&quot;/EIPS/eip-7702&quot;&gt;EIP-7702&lt;/a&gt;, since the authority’s nonce is always incremented after an authorization is applied, which conflicts with the condition required for contract deployment.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;EIP-684 defines two conditions for contract deployment: the destination address must have zero nonce and zero code length. Unfortunately, this is not sufficient. Before &lt;a href=&quot;/EIPS/eip-161&quot;&gt;EIP-161&lt;/a&gt; was applied, the nonce of a newly deployed contract remained set to zero. Therefore, it was entirely possible to create a contract with a zero nonce and zero code length but with non-empty storage, if slots were set in the constructor. There exists 28 such contracts on Ethereum mainnet at this time.&lt;/p&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This is an execution layer upgrade, and so it requires a hard fork.&lt;/p&gt;

&lt;h2 id=&quot;test-cases&quot;&gt;Test Cases&lt;/h2&gt;

&lt;p&gt;There exists quite a number of tests in the ethereum tests repo as well as in the execution spec tests, which test the scenario of deployment to targets with non-empty storage. These tests have been considered problematic in the past; Reth and EELS both intentionally implement a version of the account reset solely to pass the tests. Py-evm declared the situation impossible and never implemented account reset.&lt;/p&gt;

&lt;p&gt;Refilling the existing tests will provide sufficient coverage for this EIP.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;This EIP is a security upgrade: it enforces the immutability of deployed code.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Fri, 02 Feb 2024 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-7610</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-7610</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Network Upgrade Inclusion Stages</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #7723 - Network Upgrade Inclusion Stages&lt;/strong&gt; is in Last Call status. It is authored by Tim Beiko (@timbeiko), Alex Stokes (@ralexstokes) and was originally created 2024-06-12. It is in the  category of type Meta. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/eip-7723-network-upgrade-inclusion-stages/20281&quot;&gt;https://ethereum-magicians.org/t/eip-7723-network-upgrade-inclusion-stages/20281&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;Define the stages that EIPs go through in the process of planning network upgrades: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proposed for Inclusion&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Included&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;This EIP proposes definitions for the various stages EIPs go through when planning network upgrades. It also provides context and guidelines around when and how EIPs should be moved from one stage to the next.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;p&gt;All EIP statuses apply to a single network upgrade. EIPs must be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proposed&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled&lt;/code&gt; separately for each network upgrade. While an EIP cannot be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Included&lt;/code&gt; in two network upgrades, an EIP being &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt; in a previous upgrade does not prevent it from being &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proposed&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled&lt;/code&gt; for inclusion in any future upgrade.&lt;/p&gt;

&lt;p&gt;The statuses below are generally defined for Core EIPs, which must be activated synchronously by all nodes on a network. To help with prioritization and communications, non-Core EIPs may also be assigned these statuses. The differences in the process and implications for non-Core EIPs are noted in each status definition.&lt;/p&gt;

&lt;h3 id=&quot;upgrade-meta-eips&quot;&gt;Upgrade Meta EIPs&lt;/h3&gt;

&lt;p&gt;Anyone &lt;strong&gt;MAY&lt;/strong&gt; draft a Meta EIP to list EIPs for a network upgrade. This Meta EIP &lt;strong&gt;SHOULD&lt;/strong&gt; include four categories in its specification section: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proposed for Inclusion&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt;. Even if a category is empty, it &lt;strong&gt;SHOULD&lt;/strong&gt; be included in the initial draft for clarity.&lt;/p&gt;

&lt;p&gt;When the Upgrade Meta EIP is moved to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Last Call&lt;/code&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proposed for Inclusion&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt; lists &lt;strong&gt;SHOULD&lt;/strong&gt; be removed, leaving only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before the Upgrade Meta EIP is moved to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Final&lt;/code&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt; stage &lt;strong&gt;MUST&lt;/strong&gt; be renamed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Included&lt;/code&gt; and contain only EIPs that were activated in the upgrade.&lt;/p&gt;

&lt;h3 id=&quot;upgrade-devnets&quot;&gt;Upgrade Devnets&lt;/h3&gt;

&lt;p&gt;When preparing a network upgrade, client developers typically implement EIPs first on an ephemeral test network (upgrade devnet) to verify client interoperability, before deploying to long-lived test networks. These upgrade devnets follow a naming convention of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;upgradeName-devnet-version&lt;/code&gt; (e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pectra-devnet-0&lt;/code&gt; for the first upgrade devnet of the Pectra network upgrade, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dencun-devnet-1&lt;/code&gt; for the second upgrade devnet of the Dencun update, etc).&lt;/p&gt;

&lt;p&gt;Since client developers’ ability to include EIPs in a network upgrade is constrained by what can be implemented and tested in these upgrade devnets, the &lt;a href=&quot;#considered-for-inclusion&quot;&gt;Considered for Inclusion&lt;/a&gt; and &lt;a href=&quot;#scheduled-for-inclusion&quot;&gt;Scheduled for Inclusion&lt;/a&gt; sections below propose aligning these statuses with EIPs’ implementation status in upgrade devnets.&lt;/p&gt;

&lt;h3 id=&quot;proposed-for-inclusion&quot;&gt;Proposed for Inclusion&lt;/h3&gt;

&lt;p&gt;To propose an EIP for inclusion, someone &lt;strong&gt;MUST&lt;/strong&gt; open a pull request to add it to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proposed for Inclusion&lt;/code&gt; section of the Upgrade Meta EIP. The proposer of an EIP &lt;strong&gt;SHOULD&lt;/strong&gt; serve as the primary point of contact for that EIP for the duration of the upgrade cycle or &lt;strong&gt;SHOULD&lt;/strong&gt; designate another person to serve in that role. Reasonable pull requests &lt;strong&gt;SHOULD&lt;/strong&gt; be merged in a timely fashion by the Upgrade Meta EIP author.&lt;/p&gt;

&lt;p&gt;At this stage, implementation teams &lt;strong&gt;SHOULD&lt;/strong&gt; review the EIP. For Core EIPs, this should be in the context of including it in the next upgrade. For non-Core EIPs, this should be in the context of supporting the EIP before the network upgrade is activated.&lt;/p&gt;

&lt;p&gt;Note that EIPs must be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proposed for Inclusion&lt;/code&gt; for each network upgrade. In other words, proposals do not “carry over” to the next upgrade if an EIP is not included in the one it was first proposed for.&lt;/p&gt;

&lt;h3 id=&quot;considered-for-inclusion&quot;&gt;Considered for Inclusion&lt;/h3&gt;

&lt;p&gt;Once client developers have reviewed an EIP which was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proposed for Inclusion&lt;/code&gt;, they &lt;strong&gt;MAY&lt;/strong&gt; move it to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt; stage. Once a decision is made by client teams to move an EIP to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt;, the Upgrade Meta EIP &lt;strong&gt;SHOULD&lt;/strong&gt; be updated to reflect this.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt; signals that client developers are positive towards the EIP. A Core EIP that is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt;  &lt;strong&gt;SHOULD&lt;/strong&gt; be implemented in future Upgrade Devnets. Assuming it meets all the requirements for mainnet deployment it &lt;strong&gt;MAY&lt;/strong&gt; be included in the network upgrade. This stage is similar to “concept ACK” in other open source projects, and is not sufficient to result in deployment to mainnet.&lt;/p&gt;

&lt;p&gt;Non-Core EIPs that are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt; &lt;strong&gt;SHOULD&lt;/strong&gt; be supported prior to the network upgrade being activated.&lt;/p&gt;

&lt;p&gt;An EIP &lt;strong&gt;MAY&lt;/strong&gt; be moved from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt; if client teams are against including the EIP in the network upgrade.&lt;/p&gt;

&lt;p&gt;An EIP &lt;strong&gt;SHOULD&lt;/strong&gt; have a Python implementation accompanied by tests in &lt;a href=&quot;https://github.com/ethereum/execution-specs/blob/78fb726158c69d8fa164e28f195fabf6ab59b915/README.md&quot;&gt;execution-specs&lt;/a&gt; submitted as an open PR. The EIP writer is encouraged to reach out to the maintainers of execution-specs for assistance with implementation. Client developers &lt;strong&gt;MAY&lt;/strong&gt; decide to allow an EIP to be moved to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt; without either implementation, being aware that the absence of these implementations could lead to delays in the testing cycle.&lt;/p&gt;

&lt;p&gt;Any updates to an EIP that is already at this stage &lt;strong&gt;SHOULD&lt;/strong&gt; be accompanied by the appropriate updates to its implementation and tests in &lt;a href=&quot;https://github.com/ethereum/execution-specs/blob/78fb726158c69d8fa164e28f195fabf6ab59b915/README.md&quot;&gt;execution-specs&lt;/a&gt; if deemed necessary by client developers.&lt;/p&gt;

&lt;h3 id=&quot;declined-for-inclusion&quot;&gt;Declined for Inclusion&lt;/h3&gt;

&lt;p&gt;At any time during the network upgrade planning process, client developers &lt;strong&gt;MAY&lt;/strong&gt; move EIPs from any other stage to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt; stage if client teams are against including the EIP in the network upgrade. Once a decision is made by client teams to move an EIP to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt;, the Upgrade Meta EIP &lt;strong&gt;SHOULD&lt;/strong&gt; be updated to reflect this.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt; signals that client developers wish to exclude the EIP from the current network upgrade and stop discussing its potential inclusion or implementation status in relation to this upgrade. An EIP which was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt; in a particular upgrade &lt;strong&gt;MAY&lt;/strong&gt; still be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proposed for Inclusion&lt;/code&gt; in a subsequent upgrade. In exceptional circumstances, client developers &lt;strong&gt;MAY&lt;/strong&gt; choose to move an EIP from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;scheduled-for-inclusion&quot;&gt;Scheduled for Inclusion&lt;/h3&gt;

&lt;p&gt;When client teams agree to implement a Core EIP in the &lt;strong&gt;next&lt;/strong&gt; Upgrade Devnet, the EIP &lt;strong&gt;SHOULD&lt;/strong&gt; move to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt; stage, and the Upgrade Meta EIP &lt;strong&gt;SHOULD&lt;/strong&gt; be updated to reflect this. Non-Core EIPs &lt;strong&gt;SHOULD&lt;/strong&gt; move to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt; when client teams agree to immediately prioritize their implementation.&lt;/p&gt;

&lt;p&gt;An EIP &lt;strong&gt;MUST&lt;/strong&gt; have a Python implementation accompanied by tests in &lt;a href=&quot;https://github.com/ethereum/execution-specs/blob/78fb726158c69d8fa164e28f195fabf6ab59b915/README.md&quot;&gt;execution-specs&lt;/a&gt;, submitted as an open PR or merged to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;devnets/upgradeName/version&lt;/code&gt; branch of the repository. Client developers &lt;strong&gt;MAY&lt;/strong&gt; decide to allow an EIP to be moved to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt; without an &lt;a href=&quot;https://github.com/ethereum/execution-specs/blob/78fb726158c69d8fa164e28f195fabf6ab59b915/README.md&quot;&gt;execution-specs&lt;/a&gt; implementation, but the tests are strictly mandatory.&lt;/p&gt;

&lt;p&gt;Any updates to an EIP that is already at this stage &lt;strong&gt;MUST&lt;/strong&gt; be accompanied by appropriate updates to its implementation and tests in &lt;a href=&quot;https://github.com/ethereum/execution-specs/blob/78fb726158c69d8fa164e28f195fabf6ab59b915/README.md&quot;&gt;execution-specs&lt;/a&gt; if deemed necessary by client developers.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt; signals that implementation and testing work are underway. The EIP &lt;strong&gt;SHOULD&lt;/strong&gt; be included in the network upgrade if no issues arise. The latest Upgrade Devnet must contain all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt; Core EIPs.&lt;/p&gt;

&lt;p&gt;An EIP &lt;strong&gt;MAY&lt;/strong&gt; be moved from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt; if client teams are against including the EIP in the network upgrade. An EIP &lt;strong&gt;MAY&lt;/strong&gt; also be moved from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt; if client teams are in favor of including the EIP in the network upgrade but cannot commit to including it in the &lt;strong&gt;next&lt;/strong&gt; Upgrade Devnet.&lt;/p&gt;

&lt;h3 id=&quot;included&quot;&gt;Included&lt;/h3&gt;

&lt;p&gt;After network upgrade activation, all included Core EIPs and activated non-Core EIPs &lt;strong&gt;MUST&lt;/strong&gt; be moved to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Included&lt;/code&gt; in the Meta EIP. All other status lists &lt;strong&gt;MUST&lt;/strong&gt; be removed from the Meta EIP.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Included&lt;/code&gt; signals that the EIPs have been activated as part of the network upgrade.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;Formalizing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Proposed for Inclusion&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Considered for Inclusion&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scheduled for Inclusion&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Declined for Inclusion&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Included&lt;/code&gt; stages provides better legibility to both protocol maintainers and the broader Ethereum community.&lt;/p&gt;

&lt;p&gt;The specification tries to minimize steps which &lt;strong&gt;MUST&lt;/strong&gt; be followed to align with Ethereum’s “rough consensus” governance model.&lt;/p&gt;

&lt;p&gt;Assuming it is adopted, the process outlined in this EIP should be used for at least one full network upgrade cycle before moving to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Last Call&lt;/code&gt; and at least two full network upgrades cycles before moving to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Final&lt;/code&gt;. This way, the EIP can be updated to reflect changes made to the process over time.&lt;/p&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This EIP does not directly change the Ethereum protocol. It formalizes parts of the current network upgrade planning process.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;None.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-7723</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-7723</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>Code Index</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #7744 - Code Index&lt;/strong&gt; is in Last Call status. It is authored by Tim Pechersky (@peersky) &lt;t@peersky.xyz&gt; and was originally created 2024-07-16. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/erc-7744-code-index/20569&quot;&gt;https://ethereum-magicians.org/t/erc-7744-code-index/20569&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This EIP defines a standard interface for indexing smart contracts on Ethereum by their bytecode hash. This enables trustless discovery and verification of contract code, facilitating use cases like bytecode signing, whitelisting, and decentralized distribution mechanisms.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;Existing contract discovery relies on addresses, which are non-deterministic and can be obfuscated through proxies. Indexing by bytecode hash provides a deterministic and tamper-proof way to identify and verify contract code, enhancing security and trust in the Ethereum ecosystem.&lt;/p&gt;

&lt;p&gt;Consider a security auditor who wants to attest to the integrity of a contract’s code. By referencing bytecode hashes, auditors can focus their audit on the bytecode itself, without needing to assess deployment parameters or storage contents. This method verifies the integrity of a contract’s codebase without auditing the entire contract state.&lt;/p&gt;

&lt;p&gt;Additionally, bytecode referencing allows whitelist contracts before deployment, allowing developers to get pre-approval for their codebase without disclosing the code itself, or even pre-setup infrastructure that will change it behavior upon adding some determined functionality on chain.&lt;/p&gt;

&lt;p&gt;For developers relying on extensive code reuse, bytecode referencing protects against malicious changes that can occur with address-based referencing through proxies. This builds long-term trust chains extending to end-user applications.&lt;/p&gt;

&lt;p&gt;For decentralized application (dApp) developers, a code index can save gas costs by allowing them to reference existing codebases instead of redeploying them, optimizing resource usage. This can be useful for dApps that rely on extensive re-use of same codebase as own dependencies.&lt;/p&gt;

&lt;h3 id=&quot;why-this-registry-needs-to-be-an-erc&quot;&gt;Why this registry needs to be an ERC&lt;/h3&gt;

&lt;p&gt;The Code Index is essential for trustless and secure smart contract development. By standardizing the interface for indexing contracts by their bytecode, developers can easily integrate this feature into their smart contracts, enhancing the security and trustworthiness of the Ethereum ecosystem.&lt;/p&gt;

&lt;p&gt;Its simplicity and generic nature make it suitable for a wide range of applications. The ability to globally reference the same codebase makes it an ideal candidate for standardization.&lt;/p&gt;

&lt;p&gt;Ultimately, this feature should be incorporated into EIP standards, as it is a fundamental building block for trustless and secure smart contract development. This standard is a step towards this goal.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/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;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// SPDX-License-Identifier: CC0-1.0
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IERC7744&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;./IERC7744.sol&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**
 * @title Byte Code Indexer Contract
 * @notice You can use this contract to index contracts by their bytecode.
 * @dev This allows to query contracts by their bytecode instead of addresses.
 * @author Tim Pechersky (@Peersky)
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7744&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC7744&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isEIP7702&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;assembly&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;extcodecopy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Copy first 3 bytes to memory
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Load the 3 bytes from memory
&lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xef0100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isValidContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codeHash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codehash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;codeHash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isEIP7702&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice Registers a contract in the index by its bytecode hash
     * @param container The contract to register
     * @dev `msg.codeHash` will be used
     * @dev It will revert if the contract is already indexed or if returns EIP7702 delegated EOA
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;etalon&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codehash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isValidContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Invalid container&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;etalon&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isValidContainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;etalon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;revert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alreadyExists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codehash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codehash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;emit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Indexed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codehash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;cm&quot;&gt;/**
     * @notice Returns the contract address by its bytecode hash
     * @dev returns zero if the contract is not indexed
     * @param id The bytecode hash
     * @return The contract address
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes32&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;deployment-method&quot;&gt;Deployment method&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CodeIndex&lt;/code&gt; contract is deployed at: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xC0De1D1126b6D698a0073A4e66520111cEe22F62&lt;/code&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CREATE2&lt;/code&gt; via the deterministic deployer at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x4e59b44847b379578588920ca78fbf26c0b4956c&lt;/code&gt; with a salt of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x9425035d50edcd7504fe5eeb5df841cc74fe6cccd82dca6ee75bcdf774bd88d9&lt;/code&gt; is obtained by seeking a vanity address starting with meaningful name “Code ID (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c0de1d&lt;/code&gt;) for a bytecode compiled with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;solc 0.8.28&lt;/code&gt; as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;solc --input-file src/ERC7744.sol --bin --optimize --optimize-runs 2000 --metadata-hash none --via-ir --optimize-yul&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bytecode over Addresses&lt;/strong&gt;: Bytecode is deterministic and can be verified on-chain, while addresses are opaque and mutable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reverting on re-indexing&lt;/strong&gt;: There is small, yet non-zero probability of hash collision attack. Disallowing updates to indexed location of bytecode coupes with this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple Interface&lt;/strong&gt;: The interface is minimal and focused to maximize composability and ease of implementation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Library Implementation&lt;/strong&gt;: Implementing this as a library would limit its impact, making code reuse more difficult and lacking a single, official source of truth. By establishing this as an ERC, we ensure standardization and widespread adoption, driving the ecosystem forward.&lt;/p&gt;

&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;/h2&gt;

&lt;p&gt;Reference implementation of the Code Index can be found in the assets folder. There you can find the &lt;a href=&quot;/assets/eip-7744/IERC7744.sol&quot;&gt;interface&lt;/a&gt; and the &lt;a href=&quot;/assets/eip-7744/ERC7744.sol&quot;&gt;implementation&lt;/a&gt; of the Code Index.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Malicious Code&lt;/strong&gt;: The index does NOT guarantee the safety or functionality of indexed contracts. Users MUST exercise caution and perform their own due diligence before interacting with indexed contracts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Storage contents of registered contracts&lt;/strong&gt;: The index only refers to the bytecode of the contract, not the storage contents. This means that the contract state is not indexed and may change over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;/EIPS/eip-7702&quot;&gt;EIP-7702&lt;/a&gt;&lt;/strong&gt;: The index does not index the EIP-7702 delegated accounts. During attempt to register, it checks if contract code begins with reserved delegation designator &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xef0100&lt;/code&gt; and if so, it will revert.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-Destruct Contracts&lt;/strong&gt;: In case of indexed contract storage becomes empty, contracts may be re-indexed, During register function call, if contract is already indexed, we run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isValidContainer&lt;/code&gt; check on the indexed address. It it fails, re-indexing is allowed with a newly specified address.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Tue, 16 Jul 2024 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-7744</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-7744</guid>
      </item>
      
    
      
    
      
      
      <item>
        <title>Composable Security Middleware Hooks</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #7746 - Composable Security Middleware Hooks&lt;/strong&gt; is in Last Call status. It is authored by Tim Pechersky (@peersky) and was originally created 2024-07-17. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/erc-7746-composable-security-middleware-hooks/19471&quot;&gt;https://ethereum-magicians.org/t/erc-7746-composable-security-middleware-hooks/19471&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This EIP proposes a standard interface, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ILayer&lt;/code&gt;, for implementing composable security layers in smart contracts. These layers act as middleware, enabling runtime validation of function calls before and after execution, independent of the protected contract’s logic. This approach facilitates modular security, allowing independent providers to manage and upgrade security layers across multiple contracts.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;Current smart contract security practices often rely on monolithic validation logic within the contract itself. This can lead to tightly coupled code, making it difficult to isolate and address security concerns. Better structured architecture is needed, middleware like approach is widely used in the industry, allowing to wrap calls in other calls in generic and repeatable pattern with same call signatures.&lt;/p&gt;

&lt;p&gt;The Security Layers Standard introduces a modular approach, enabling:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Independent Security Providers:&lt;/strong&gt; Specialized security providers can focus on developing and maintaining specific security checks.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Composable Security:&lt;/strong&gt; Layers can be combined to create comprehensive security profiles tailored to individual contract needs.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Upgradability:&lt;/strong&gt; Security layers can be updated without requiring changes to the protected contract.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Flexibility:&lt;/strong&gt; Layers can perform a wide range of validation checks, including access control, input sanitization, output verification, and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having a generalized standard for such layers can help to build more secure and modular systems as well as enable security providers to build generic, service-oriented security oracle solutions.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/h2&gt;

&lt;p&gt;A contract implementing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ILayer&lt;/code&gt; interface MUST provide two functions:&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// SPDX-License-Identifier: CC0-1.0
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;solidity&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ILayer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// @notice Validates a function call before execution.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param configuration Layer-specific configuration data.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param selector The function selector being called.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param sender The address initiating the call.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param value The amount of ETH sent with the call (if any).
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param data The calldata for the function call.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return beforeCallResult Arbitrary data to be passed to `afterCallValidation`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev MUST revert if validation fails.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;beforeCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes4&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Validates a function call after execution.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param configuration Layer-specific configuration data.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param selector The function selector being called.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param sender The address initiating the call.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param value The amount of ETH sent with the call (if any).
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param data The calldata for the function call.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param beforeCallResult The data returned by `beforeCallValidation`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev MUST revert if validation fails.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;afterCall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes4&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;beforeCallResult&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A protected contract MAY integrate security layers by calling the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;beforeCallValidation&lt;/code&gt; function before executing its logic and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;afterCallValidation&lt;/code&gt; function afterwards. Multiple layers can be registered and executed in a defined order. The protected contract MUST revert if any layer reverts.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;: The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layerConfig&lt;/code&gt; parameter allows for layer-specific customization, enabling a single layer implementation to serve multiple contracts with varying requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;non-static calls&lt;/strong&gt;: Layers can maintain their own state, allowing for more complex validation logic (e.g., rate limiting, usage tracking).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strict Validation&lt;/strong&gt;: Reverts on validation failure ensure a fail-safe mechanism, preventing execution of potentially harmful transactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gas Costs&lt;/strong&gt;: Layers naturally will have gas costs associated with their execution. However, the benefits of enhanced security and modularity outweigh these costs, especially as blockchain technology continues to evolve and we expect gas costs to decrease over time.&lt;/p&gt;

&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;/h2&gt;

&lt;p&gt;A reference implementation of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ILayer&lt;/code&gt; interface and a sample protected contract can be found in the repository:
In the &lt;a href=&quot;/assets/eip-7746/ILayer.sol&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ILayer.sol&lt;/code&gt;&lt;/a&gt; a reference interface is provided.&lt;/p&gt;

&lt;p&gt;In this test, a &lt;a href=&quot;/assets/eip-7746/test/Protected.sol&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Protected.sol&lt;/code&gt;&lt;/a&gt; contract is protected by a &lt;a href=&quot;/assets/eip-7746/test/RateLimitLayer.sol&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RateLimitLayer.sol&lt;/code&gt;&lt;/a&gt; layer. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RateLimitLayer&lt;/code&gt; implements the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ILayer&lt;/code&gt; interface and enforces a rate which client has configured.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Drainer&lt;/code&gt; simulates a vulnerable contract that acts in a malicious way. In the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test.ts&lt;/code&gt; The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Drainer&lt;/code&gt; contract is trying to drain the funds from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Protected&lt;/code&gt; contract. It is assumed that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Protected&lt;/code&gt; contract has bug that allows partial unauthorized access to the state.
The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RateLimitLayer&lt;/code&gt; is configured to allow only 10 transactions per block from same sender. The test checks that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Drainer&lt;/code&gt; contract is not able to drain the funds from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Protected&lt;/code&gt; contract.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Layer Trust&lt;/strong&gt;: Thoroughly audit and vet any security layer before integrating it into your contract. Malicious layers can compromise contract security.&lt;/p&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Wed, 17 Jul 2024 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-7746</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-7746</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
      
      <item>
        <title>uRWA - Universal Real World Asset Interface</title>
        <description>
        &lt;p&gt;&lt;strong&gt;EIP #7943 - uRWA - Universal Real World Asset Interface&lt;/strong&gt; is in Last Call status. It is authored by Dario Lo Buglio (@xaler5), Tino Martinez Molina (@tinom9), Mihai Colceriu (@mihaic195) and was originally created 2025-06-10. It is in the ERC category of type Standards Track. Please review and note any changes that should block acceptance.&lt;/p&gt;
        
          &lt;p&gt;The author has requested that discussions happen at the following URL: &lt;a href=&quot;https://ethereum-magicians.org/t/erc-universal-rwa-interface/23972&quot;&gt;https://ethereum-magicians.org/t/erc-universal-rwa-interface/23972&lt;/a&gt;&lt;/p&gt;
        
        &lt;hr /&gt;
        &lt;h2 id=&quot;abstract&quot;&gt;Abstract&lt;/h2&gt;

&lt;p&gt;This EIP proposes the Universal RWA (uRWA) standard, a set of interfaces for tokenized Real World Assets (RWAs) such as securities, real estate, commodities, or other physical/financial assets on the blockchain.&lt;/p&gt;

&lt;p&gt;Real World Assets often require regulatory compliance features not found in standard tokens, including the ability to freeze assets, perform enforcement transfers for legal compliance, and restrict transfers to authorized users. The uRWA standard extends common token standards like &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt;, or &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt; by introducing essential compliance functions while remaining minimal and not opinionated about specific implementation details.&lt;/p&gt;

&lt;p&gt;This enables DeFi protocols and applications to interact with tokenized real-world assets in a standardized way, knowing they can check transfer permissions, whether users are allowed to interact, handle frozen assets appropriately, and integrate with compliant RWA tokens regardless of the underlying asset type or internal compliance logic. It also adopts &lt;a href=&quot;/EIPS/eip-165&quot;&gt;ERC-165&lt;/a&gt; for introspection.&lt;/p&gt;

&lt;h2 id=&quot;motivation&quot;&gt;Motivation&lt;/h2&gt;

&lt;p&gt;Real World Assets (RWAs) represent a significant opportunity to bridge traditional finance and decentralized finance (DeFi). By tokenizing assets like real estate, corporate bonds, commodities, art, or securities, we can unlock benefits such as fractional ownership, programmable compliance, enhanced liquidity through secondary markets for traditionally illiquid assets, and integration with decentralized protocols.&lt;/p&gt;

&lt;p&gt;However, tokenizing real world assets introduces regulatory requirements often absent in purely digital assets, such as allowlists for users, transfer restrictions, asset freezing, or law enforcement rules. Existing token standards like &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt;, and &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt; lack the inherent structure to address these compliance needs directly within the standard itself.&lt;/p&gt;

&lt;p&gt;Attempts at defining universal RWA standards historically imposed unnecessary complexity and gas overhead for simpler use cases that do not require the full spectrum of features like granular role-based access control, mandatory on-chain whitelisting, specific on-chain identity solutions, or metadata handling solutions mandated by the standard.&lt;/p&gt;

&lt;p&gt;Additionally, the broad spectrum of RWA classes inherently suggests the need to move away from a one-size-fits-all solution. This means a minimalistic approach, an unopinionated features list, and maximal compatibility have been kept in mind as design goals.&lt;/p&gt;

&lt;p&gt;The uRWA standard seeks a more refined balance by defining an essential interface, establishing a common ground for interaction regarding compliance and control, without dictating the underlying implementation mechanisms. This allows core token implementations to remain lean while providing standard functions for RWA-specific interactions.&lt;/p&gt;

&lt;p&gt;The final goal is to build composable DeFi around RWAs, providing the same interface when dealing with compliance and regulation.&lt;/p&gt;

&lt;h2 id=&quot;specification&quot;&gt;Specification&lt;/h2&gt;

&lt;p&gt;The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHOULD”, and “MAY” in this document are to be interpreted as described in RFC 2119 and RFC 8174.&lt;/p&gt;

&lt;p&gt;The following defines the standard interfaces for an &lt;a href=&quot;/EIPS/eip-7943&quot;&gt;ERC-7943&lt;/a&gt; token contract, which MUST extend from one base token interface such as &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt;, or &lt;a href=&quot;/EIPS/eip-6909&quot;&gt;ERC-6909&lt;/a&gt;. Note that &lt;a href=&quot;/EIPS/eip-6909&quot;&gt;ERC-6909&lt;/a&gt;-based implementations can use the multi token interface:&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;/// @notice Interface for ERC-20 based implementations.
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC7943Fungible&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC165&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// @notice Emitted when tokens are taken from one address and transferred to another.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address from which tokens were taken.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address to which seized tokens were transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount seized.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ForcedTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Emitted when `setFrozenTokens` is called, changing the frozen `amount` of tokens for `account`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account whose tokens are being frozen.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount of tokens frozen after the change.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Frozen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when an account is not allowed to send tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account which is not allowed to send.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943CannotSend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when an account is not allowed to receive tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account which is not allowed to receive.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943CannotReceive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when a transfer is not allowed according to internal rules.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address from which tokens are being sent.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address to which tokens are being sent.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount sent.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943CannotTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when a transfer is attempted from `account` with an `amount` less than or equal to its balance, but greater than its unfrozen balance.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address holding the tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount being transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param unfrozen The amount of tokens that are unfrozen and available to transfer.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943InsufficientUnfrozenBalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unfrozen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Takes tokens from one address and transfers them to another.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev Requires specific authorization. Used for regulatory compliance or recovery scenarios.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address from which `amount` is taken.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address that receives `amount`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount to force transfer.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return result True if the transfer executed correctly. Reverts on failure.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forcedTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Changes the frozen status of `amount` tokens belonging to `account`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev Overwrites the current value, similar to an `approve` function.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// Requires specific authorization. Frozen tokens cannot be transferred by the account.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account whose tokens are to be frozen.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount of tokens to freeze. It can be greater than the account balance.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return result True if the freezing executed correctly. Reverts on failure.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setFrozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks if a specific account is allowed to send tokens according to token rules.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev This is often used for allowlist/KYC/KYB/AML checks.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address to check.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return allowed True if the account is allowed to send, false otherwise.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canSend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks if a specific account is allowed to receive tokens according to token rules.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev This is often used for allowlist/KYC/KYB/AML checks.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address to check.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return allowed True if the account is allowed to receive, false otherwise.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canReceive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks the frozen status/amount.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev It could return an amount higher than the account&apos;s balance.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return amount The amount of tokens currently frozen for `account`.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getFrozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks if a transfer is currently possible according to token rules. It enforces validations on the frozen tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev This can involve checks like allowlists, blocklists, transfer limits, and other policy-defined restrictions.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address sending tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address receiving tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount being transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return allowed True if the transfer is allowed, false otherwise.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;/// @notice Interface for ERC-721 based implementations.
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC7943NonFungible&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC165&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// @notice Emitted when `tokenId` is taken from one address and transferred to another.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address from which `tokenId` is taken.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address to which seized `tokenId` is transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being transferred.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ForcedTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Emitted when `setFrozenTokens` is called, changing the frozen status of `tokenId` for `account`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account whose `tokenId` is subjected to freeze/unfreeze.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token subjected to freeze/unfreeze.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param frozenStatus Whether `tokenId` has been frozen or unfrozen.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Frozen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frozenStatus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when an account is not allowed to send tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account which is not allowed to send.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943CannotSend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when an account is not allowed to receive tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account which is not allowed to receive.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943CannotReceive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when a transfer is not allowed according to internal rules.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address from which tokens are being sent.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address to which tokens are being sent.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being sent.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943CannotTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when a transfer is attempted from `account` with a `tokenId` which has been previously frozen.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address holding the token with `tokenId`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being frozen and unavailable to be transferred.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943InsufficientUnfrozenBalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Takes `tokenId` from one address and transfers it to another.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev Requires specific authorization. Used for regulatory compliance or recovery scenarios.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address from which `tokenId` is taken.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address that receives `tokenId`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return result True if the transfer executed correctly. Reverts on failure.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forcedTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Changes the frozen status of `tokenId` belonging to an `account`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev Overwrites the current value, similar to an `approve` function.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// Requires specific authorization. Frozen tokens cannot be transferred by the account.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account whose tokens are to be frozen.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token to freeze.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param frozenStatus Whether `tokenId` is being frozen or not.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return result True if the freezing executed correctly. Reverts on failure.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setFrozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frozenStatus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks if a specific account is allowed to send tokens according to token rules.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev This is often used for allowlist/KYC/KYB/AML checks.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address to check.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return allowed True if the account is allowed to send, false otherwise.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canSend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks if a specific account is allowed to receive tokens according to token rules.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev This is often used for allowlist/KYC/KYB/AML checks.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address to check.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return allowed True if the account is allowed to receive, false otherwise.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canReceive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks the frozen status of a specific `tokenId`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev It could return true even if the account does not hold the token.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return frozenStatus Whether `tokenId` is currently frozen for `account`.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getFrozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frozenStatus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks if a transfer is currently possible according to token rules. It enforces validations on the frozen tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev This can involve checks like allowlists, blocklists, transfer limits, and other policy-defined restrictions.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address sending tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address receiving tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return allowed True if the transfer is allowed, false otherwise.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;/// @notice Interface for ERC-1155 based implementations.
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC7943MultiToken&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC165&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// @notice Emitted when tokens are taken from one address and transferred to another.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address from which tokens were taken.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address to which seized tokens were transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount seized.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ForcedTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Emitted when `setFrozenTokens` is called, changing the frozen `amount` of `tokenId` tokens for `account`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account whose tokens are being frozen.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being frozen.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount of tokens frozen after the change.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Frozen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;indexed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when an account is not allowed to send tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account which is not allowed to send.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943CannotSend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when an account is not allowed to receive tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account which is not allowed to receive.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943CannotReceive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when a transfer is not allowed according to internal rules.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address from which tokens are being sent.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address to which tokens are being sent.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being sent.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount sent.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943CannotTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Error reverted when a transfer is attempted from `account` with an `amount` of `tokenId` less than or equal to its balance, but greater than its unfrozen balance.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address holding the `amount` of `tokenId` tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount of `tokenId` tokens being transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param unfrozen The amount of tokens that are unfrozen and available to transfer.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943InsufficientUnfrozenBalance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unfrozen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Takes tokens from one address and transfers them to another.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev Requires specific authorization. Used for regulatory compliance or recovery scenarios.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address from which `amount` is taken.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address that receives `amount`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount to force transfer.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return result True if the transfer executed correctly. Reverts on failure.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;forcedTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Changes the frozen status of `amount` of `tokenId` tokens belonging to an `account`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev Overwrites the current value, similar to an `approve` function.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// Requires specific authorization. Frozen tokens cannot be transferred by the account.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account whose tokens are to be frozen.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token to freeze.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount of tokens to freeze. It can be greater than the account balance.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return result True if the freezing executed correctly. Reverts on failure.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setFrozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks if a specific account is allowed to send tokens according to token rules.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev This is often used for allowlist/KYC/KYB/AML checks.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address to check.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return allowed True if the account is allowed to send, false otherwise.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canSend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks if a specific account is allowed to receive tokens according to token rules.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev This is often used for allowlist/KYC/KYB/AML checks.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address to check.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return allowed True if the account is allowed to receive, false otherwise.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canReceive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks the frozen status/amount of a specific `tokenId`.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev It could return an amount higher than the account&apos;s balance.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param account The address of the account.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return amount The amount of `tokenId` tokens currently frozen for `account`.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getFrozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// @notice Checks if a transfer is currently possible according to token rules. It enforces validations on the frozen tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @dev This can involve checks like allowlists, blocklists, transfer limits, and other policy-defined restrictions.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param from The address sending tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param to The address receiving tokens.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param tokenId The ID of the token being transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @param amount The amount being transferred.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;/// @return allowed True if the transfer is allowed, false otherwise.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;cansend-canreceive-cantransfer-and-getfrozentokens&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getFrozenTokens&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;These provide views into the implementing contract’s compliance, transfer policy logic, and freezing status.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt; are account-level eligibility checks, independent of any specific transfer parameters (counterparty, amount, or token identifier). These functions:
    &lt;ul&gt;
      &lt;li&gt;MUST NOT revert.&lt;/li&gt;
      &lt;li&gt;MUST NOT change the storage of the contract.&lt;/li&gt;
      &lt;li&gt;MAY depend on on-chain state such as current timestamp, block number, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.sender&lt;/code&gt;.&lt;/li&gt;
      &lt;li&gt;MUST NOT encode transfer-specific or quantitative rules (e.g., balance checks, amount limits). Those belong in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt; is a transfer-level authorization check that evaluates whether a specific transfer is permissible under permissioned compliance rules. This function:
    &lt;ul&gt;
      &lt;li&gt;MUST NOT revert.&lt;/li&gt;
      &lt;li&gt;MUST NOT change the storage of the contract.&lt;/li&gt;
      &lt;li&gt;MAY depend on on-chain state such as current timestamp, block number, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg.sender&lt;/code&gt;.&lt;/li&gt;
      &lt;li&gt;MUST validate that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amount&lt;/code&gt; being transferred doesn’t exceed the unfrozen amount (which is the difference between the current balance and the frozen balance).&lt;/li&gt;
      &lt;li&gt;MUST perform a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt; check on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from&lt;/code&gt; parameter and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt; check on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to&lt;/code&gt; parameter. Note that &lt;a href=&quot;/EIPS/eip-3643&quot;&gt;ERC-3643&lt;/a&gt; does not perform this check within &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt; as this standard requires.&lt;/li&gt;
      &lt;li&gt;MUST return false if any permissioned rule would prevent a given transfer from succeeding. A transfer refers to any operation that emits the token’s canonical transfer event. A permissioned check can be a pausing mechanism, a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt;, or anything else that requires privileged actors.&lt;/li&gt;
      &lt;li&gt;MUST NOT return false based on token-specific, non-permissioned validations such as balance or allowance checks. These checks belong to the underlying base token standard (e.g., &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt;).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getFrozenTokens&lt;/code&gt; will return the absolute frozen amount, which MAY exceed the account’s current balance. In &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt; tokens, it MAY return true even if the account does not hold the token.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;forcedtransfer&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;This function provides a standard mechanism for forcing a transfer from a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from&lt;/code&gt; address to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to&lt;/code&gt; address. The function:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;MUST directly manipulate balances or ownership to transfer the asset from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to&lt;/code&gt; either by transferring or burning from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from&lt;/code&gt; and minting to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;MUST be restricted in access.&lt;/li&gt;
  &lt;li&gt;MUST perform necessary validation checks (e.g., sufficient balance/ownership of a specific token).&lt;/li&gt;
  &lt;li&gt;MUST emit the base standard’s canonical transfer event(s), consistent with the mechanism used (transfer or burn and mint), and MUST emit the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ForcedTransfer&lt;/code&gt; event.&lt;/li&gt;
  &lt;li&gt;In single-party permissioned contexts:
    &lt;ul&gt;
      &lt;li&gt;It MAY bypass the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt; checks. If this happens, and the transfer involves tokens that are currently counted as frozen, it MUST unfreeze the assets first and emit a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frozen&lt;/code&gt; event before the underlying base token transfer event reflecting the change. Having the unfrozen amount changed before the actual transfer is critical for tokens that might be susceptible to reentrancy attacks doing external checks on recipients, as is the case for &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt; and &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt; tokens.&lt;/li&gt;
      &lt;li&gt;It SHOULD at least perform a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt; check on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to&lt;/code&gt; parameter to ensure compliance.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;In multi-party permissioned contexts:
    &lt;ul&gt;
      &lt;li&gt;It SHOULD perform the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt; checks and SHOULD NOT bypass the frozen constraints.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;MUST revert in cases where validations and/or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt; checks return false or fail.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;setfrozentokens&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;It provides a way to freeze or unfreeze assets held by a specific account. This is useful for temporary lock mechanisms. This function:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;MUST emit the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frozen&lt;/code&gt; event.&lt;/li&gt;
  &lt;li&gt;MUST be restricted in access.&lt;/li&gt;
  &lt;li&gt;MUST allow freezing more assets than those held. This allows for future balances withholding.&lt;/li&gt;
  &lt;li&gt;MUST revert in cases of logical issues or validation checks failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;additional-specifications&quot;&gt;Additional Specifications&lt;/h3&gt;

&lt;p&gt;The contract MUST implement the &lt;a href=&quot;/EIPS/eip-165&quot;&gt;ERC-165&lt;/a&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;supportsInterface&lt;/code&gt; function and MUST return true for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bytes4&lt;/code&gt; value (representing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;interfaceId&lt;/code&gt;):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x3edbb4c4&lt;/code&gt; for the fungible interface.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xbf1ef5fe&lt;/code&gt; for the non-fungible interface.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x41c4fbad&lt;/code&gt; for the multi token interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implementations of these interfaces MUST implement the necessary functions of their chosen base standard (e.g., &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt; for the fungible interface, &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt; for the non-fungible interface, &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt; or &lt;a href=&quot;/EIPS/eip-6909&quot;&gt;ERC-6909&lt;/a&gt; for the multi token interface) and MUST also restrict access to sensitive functions like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt; using an appropriate access control mechanism (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;onlyOwner&lt;/code&gt;, Role-Based Access Control). The specific mechanism is NOT mandated by this interface standard.&lt;/p&gt;

&lt;p&gt;Implementations MUST ensure their transfer methods exhibit the following behavior:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Public transfers&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transfer&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transferFrom&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;safeTransferFrom&lt;/code&gt;, etc.) MUST NOT succeed in cases where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt; would return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;, or where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt; would return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt; for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;from&lt;/code&gt; address, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt; would return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt; for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;to&lt;/code&gt; address.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Minting&lt;/strong&gt; in permissionless contexts (e.g., public &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mint&lt;/code&gt; functions) MUST NOT succeed for accounts where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt; on the recipient would return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;. In permissioned contexts (e.g., authorized minting by privileged roles), minting SHOULD respect &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt; checks on the recipient, though implementations MAY bypass these checks when necessary for operational or compliance reasons.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Burning&lt;/strong&gt; in permissionless contexts (e.g., public &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;burn&lt;/code&gt; functions) MUST respect the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt; check, MUST respect the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt; check on the token holder, and MUST NOT allow burning more assets than the unfrozen amount. In permissioned contexts (e.g., authorized burning by privileged roles), burning MAY succeed for accounts where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt; on the token holder would return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt;, and MAY burn more assets than the unfrozen amount, in which case the contract MUST update the frozen status accordingly and emit a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frozen&lt;/code&gt; event before the underlying base token transfer event.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC7943CannotSend&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC7943CannotReceive&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC7943CannotTransfer&lt;/code&gt; errors MAY be used as a general revert mechanism whenever internal calls to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt; return false. They MAY be replaced by more specific errors depending on the custom checks performed inside those calls, or simply not used.&lt;/p&gt;

&lt;p&gt;In general, the standard prioritizes error specificity, meaning that specific errors such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC7943InsufficientUnfrozenBalance&lt;/code&gt; SHOULD be thrown when applicable. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC7943InsufficientUnfrozenBalance&lt;/code&gt; error SHOULD be triggered when a transfer is attempted from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;account&lt;/code&gt; with an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amount&lt;/code&gt; less than or equal to its balance, but greater than its unfrozen balance, or with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tokenId&lt;/code&gt; which is currently frozen. If the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amount&lt;/code&gt; is greater than the whole balance or the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tokenId&lt;/code&gt; is not owned by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;account&lt;/code&gt;, unrelated to the frozen amount, more specific errors from the base standard SHOULD be used instead.&lt;/p&gt;

&lt;h2 id=&quot;rationale&quot;&gt;Rationale&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Minimalism&lt;/strong&gt;: Defines only the essential functions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getFrozenTokens&lt;/code&gt;) and associated events/errors needed for common RWA compliance and control patterns, avoiding mandated complexity or opinionated features. The reason to introduce specific errors (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC7943CannotSend&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC7943CannotReceive&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC7943CannotTransfer&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC7943InsufficientUnfrozenBalance&lt;/code&gt;) is to provide completeness with the introduced functionalities (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getFrozenTokens&lt;/code&gt;). As dictated in the specifications, error specificity is prioritized, leaving space for implementations to accommodate more explicit errors. Regarding the events &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frozen&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ForcedTransfer&lt;/code&gt;, the reason for their existence is to signal &lt;em&gt;uncommon&lt;/em&gt; transfers (like in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt;) but also to help off-chain indexers correctly keep track and account for asset seizures and freezing. As mentioned in the specifications, the order in which these events are emitted in relation to the base token contract events is important in practice and merits special attention.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Separation of concerns&lt;/strong&gt;: The standard separates account-level eligibility (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt;) from transfer-level authorization (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt;). &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt; evaluate whether an account is eligible to participate independently of any specific transfer parameters such as counterparty, amount, or token identifier. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt; evaluates whether a specific transfer is permissible under permissioned compliance rules, taking into account frozen balances, transfer limits, counterparty restrictions, and account eligibility. This separation provides clear semantics for integrators and avoids confusion between account eligibility and transfer-specific validation. It also enables one-way restrictions where an account may be blocked from receiving but still allowed to send, which is common in regulated environments.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Flexible compliance&lt;/strong&gt;: Provides standard view functions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getFrozenTokens&lt;/code&gt;) for compliance checks without dictating &lt;em&gt;how&lt;/em&gt; those checks are implemented internally by the token contract. This allows diverse compliance strategies.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Compatibility&lt;/strong&gt;: Designed as an interface layer compatible with existing base standards like &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt;, and &lt;a href=&quot;/EIPS/eip-6909&quot;&gt;ERC-6909&lt;/a&gt;. Implementations extend from &lt;a href=&quot;/EIPS/eip-7943&quot;&gt;ERC-7943&lt;/a&gt; alongside their base standard interface.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Essential enforcement rules&lt;/strong&gt;: Includes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt; as standard functions, acknowledging their importance for regulatory enforcement in the RWA space, distinct from standard transfers. Mandates access control for these sensitive functions. To maintain a lean EIP, a single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt; function (which overwrites the frozen asset quantity) and one &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Frozen&lt;/code&gt; event were favored over distinct &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;freeze&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unfreeze&lt;/code&gt; functions and events.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;/EIPS/eip-165&quot;&gt;ERC-165&lt;/a&gt;&lt;/strong&gt;: Ensures implementing contracts can signal support for this interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As an example, an AMM pool or a lending protocol can integrate with &lt;a href=&quot;/EIPS/eip-7943&quot;&gt;ERC-7943&lt;/a&gt;-based &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt; tokens by calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt; to handle these assets in a compliant manner. Enforcement actions like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt; can either be called by third-party entities or be integrated by external protocols to allow for automated and programmable compliance. Users can then expand these tokens with additional features to fit the specific needs of individual asset types, such as on-chain identity systems, historical balance tracking for dividend distributions, semi-fungibility with token metadata, and other custom functionalities.&lt;/p&gt;

&lt;h3 id=&quot;extensibility&quot;&gt;Extensibility&lt;/h3&gt;

&lt;p&gt;While this ERC provides the necessary primitives for regulated assets, any additional feature can be added through extensions. A few examples:&lt;/p&gt;

&lt;p&gt;1) If for any administrative function like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt; it is necessary to attach a proof to the call, the contract can have a function that batches operations like:&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TokenWithLegalProofs&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC7943MultiToken&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setFrozenTokensWithProof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bytes&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;calldata&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;legalProof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;/// do anything with `legalProof`
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setFrozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tokenId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;2) Since the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt; function overwrites the absolute frozen amount and given the fact that the standard allows for multiple privileged accounts, some race-conditions might happen. If that’s the case, one can build an extension function that works with expected values of amounts frozen, like:&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setFrozenTokensIf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedPrev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;frozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedPrev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943ExpectedValueMismatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expectedPrev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]));&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setFrozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Alternatively, another solution can be using delta amounts:&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setFrozenTokensDelta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deltaAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;onlyOwner&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;actualValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deltaAmount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;actualValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deltaAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deltaAmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;actualValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943ExpectedValueMismatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;actualValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;actualValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setFrozenTokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;actualValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; These helpers reduce accidental overwrites and expand in functionalities but do not prevent same-block conflicting updates or mempool ordering races by different privileged actors.&lt;/p&gt;

&lt;p&gt;3) Developers can also perform several operations through the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;multicall&lt;/code&gt; patterns similar to the one defined in &lt;a href=&quot;/EIPS/eip-6357&quot;&gt;ERC-6357&lt;/a&gt; so that a mix of the given primitives with additional features can be batched in one transaction:&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;contract&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ERC7943Fungible&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IERC7943Fungible&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Multicall&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Now any combination of `setFrozenTokens`/`forcedTransfer`
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// coupled with other functionalities like the ones to blacklist/whitelist users
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// can be submitted in one transaction through the use of `multicall` function
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;4) Functionalities like pausability can be added on top, either through the use of modifiers or directly within functions implementations:&lt;/p&gt;

&lt;div class=&quot;language-solidity highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;canTransfer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;address&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint256&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;external&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;returns&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;paused&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ... other checks
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;notes-on-naming&quot;&gt;Notes on Naming&lt;/h3&gt;

&lt;p&gt;The naming conventions in this ERC were carefully chosen to establish clarity and semantic consistency within the broader RWA ecosystem while maintaining neutrality and broad applicability.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt;&lt;/strong&gt;: This term was selected for its neutrality. While names like &lt;em&gt;confiscation&lt;/em&gt;, &lt;em&gt;revocation&lt;/em&gt;, or &lt;em&gt;recovery&lt;/em&gt; describe specific motivations, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt; purely denotes the direct action of transferring assets, irrespective of the underlying reason. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt; was preferred over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forceTransfer&lt;/code&gt; to maintain backward compatibility with &lt;a href=&quot;/EIPS/eip-3643&quot;&gt;ERC-3643&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt;&lt;/strong&gt;: These names were chosen to clearly express the directional nature of account eligibility: whether an account is allowed to send or receive tokens. This separation enables one-way restrictions (e.g., an account blocked from receiving but still allowed to send), which are common in regulated environments such as KYC expiry, AML alerts, or jurisdictional constraints.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt;&lt;/strong&gt;: This name was preferred over &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isTransferAllowed&lt;/code&gt; for consistency with established RWA standards including &lt;a href=&quot;/EIPS/eip-3643&quot;&gt;ERC-3643&lt;/a&gt; and &lt;a href=&quot;/EIPS/eip-7518&quot;&gt;ERC-7518&lt;/a&gt;. This alignment promotes interoperability and reduces cognitive overhead when working across different RWA tokens.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getFrozenTokens&lt;/code&gt;&lt;/strong&gt;: These names were chosen for managing transfer restrictions and align with &lt;a href=&quot;/EIPS/eip-3643&quot;&gt;ERC-3643&lt;/a&gt; naming patterns. &lt;em&gt;Frozen&lt;/em&gt; was also selected for its general applicability to both fungible (amount-based) and non-fungible (status-based) assets, as terms like &lt;em&gt;amount&lt;/em&gt; or &lt;em&gt;asset(s)&lt;/em&gt; might not be universally fitting.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ERC7943InsufficientUnfrozenBalance&lt;/code&gt;&lt;/strong&gt;: Discussions around &lt;em&gt;insufficient&lt;/em&gt; being similar to &lt;em&gt;unavailable&lt;/em&gt; arose, where &lt;em&gt;unavailable&lt;/em&gt; might have better suggested a temporal condition like a freezing status. However, the term &lt;em&gt;available&lt;/em&gt;/&lt;em&gt;unavailable&lt;/em&gt; was also overlapping with &lt;em&gt;frozen&lt;/em&gt;/&lt;em&gt;unfrozen&lt;/em&gt; creating more confusion and duality. Finally, coupling &lt;em&gt;insufficient&lt;/em&gt; with the specified &lt;em&gt;unfrozen balance&lt;/em&gt; better represents the domain, prefix, and subject of the error, according to &lt;a href=&quot;/EIPS/eip-6093&quot;&gt;ERC-6093&lt;/a&gt; guidelines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;backwards-compatibility&quot;&gt;Backwards Compatibility&lt;/h2&gt;

&lt;p&gt;This EIP defines a new interface standard and does not alter existing ones like &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt;, &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt;, and &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt;. Standard wallets and explorers can interact with the base token functionality of implementing contracts, subject to the rules enforced by that contract’s implementation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canSend&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canReceive&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;canTransfer&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getFrozenTokens&lt;/code&gt; functions. Full support for the &lt;a href=&quot;/EIPS/eip-7943&quot;&gt;ERC-7943&lt;/a&gt; functions requires explicit integration.&lt;/p&gt;

&lt;h2 id=&quot;reference-implementation&quot;&gt;Reference Implementation&lt;/h2&gt;

&lt;p&gt;Reference implementations of uRWA for &lt;a href=&quot;/assets/eip-7943/contracts/uRWA20.sol&quot;&gt;ERC-20&lt;/a&gt;, &lt;a href=&quot;/assets/eip-7943/contracts/uRWA721.sol&quot;&gt;ERC-721&lt;/a&gt;, and &lt;a href=&quot;/assets/eip-7943/contracts/uRWA1155.sol&quot;&gt;ERC-1155&lt;/a&gt; token implementations are provided in the assets folder. They use the OpenZeppelin library and include separate send/receive whitelists and enumerable role-based access control. These examples are provided for educational purposes only and are not audited.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations&quot;&gt;Security Considerations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Access Control for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt;&lt;/strong&gt;: The security of the mechanism chosen by the implementer to restrict access to these functions is paramount. Unauthorized access could lead to asset theft. Secure patterns (multisig, timelocks) are highly recommended.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Front-running of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forcedTransfer&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setFrozenTokens&lt;/code&gt; functions&lt;/strong&gt;: Both functions are susceptible to front-running, similar to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;approve&lt;/code&gt; function of &lt;a href=&quot;/EIPS/eip-20&quot;&gt;ERC-20&lt;/a&gt;. Furthermore, if the suggestion to allow freezing more than what an account owns is not followed, any account may be incentivized to front-run attempts to freeze its balance when receiving new funds. Additional features to gradually increment or decrement the frozen status MAY be considered for implementation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Standard Contract Security&lt;/strong&gt;: Implementations MUST adhere to general smart contract security best practices (reentrancy guards where applicable, checks-effects-interactions, etc.). Specifically, in the checks-effects-interactions consideration, implementations need to be aware of tokens having hooks, especially on recipients as in &lt;a href=&quot;/EIPS/eip-721&quot;&gt;ERC-721&lt;/a&gt; or &lt;a href=&quot;/EIPS/eip-1155&quot;&gt;ERC-1155&lt;/a&gt;. In such circumstances, it might be convenient to adopt reentrancy guards to prevent unwanted executions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;copyright&quot;&gt;Copyright&lt;/h2&gt;

&lt;p&gt;Copyright and related rights waived via &lt;a href=&quot;/LICENSE&quot;&gt;CC0&lt;/a&gt;.&lt;/p&gt;

      </description>
        <pubDate>Tue, 10 Jun 2025 00:00:00 +0000</pubDate>
        <link>https://eips.ethereum.org//EIPS/eip-7943</link>
        <guid isPermaLink="true">https://eips.ethereum.org//EIPS/eip-7943</guid>
      </item>
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
      
    
  </channel>
</rss>
