<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Will Schwab</title>
        <link>https://paragraph.com/@wschwab</link>
        <description>undefined</description>
        <lastBuildDate>Sun, 08 Nov 2026 23:07:55 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Will Schwab</title>
            <url>https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/50baa4490e427c5bf7bfb25973211a2f47903c11659c0ed4c7f736dad5d9ef4a.jpg</url>
            <link>https://paragraph.com/@wschwab</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Belisarius and the Horde Chapter 2: The Contract and the Calldata]]></title>
            <link>https://paragraph.com/@wschwab/belisarius-and-the-horde-chapter-2-the-contract-and-the-calldata</link>
            <guid>ueykbH4xMxbkHMCWhDiV</guid>
            <pubDate>Thu, 24 Nov 2022 18:23:30 GMT</pubDate>
            <description><![CDATA[Trying to Disambiguate Belisarius’s Obscure Functions For an introduction to this series, see here. For quick reference, Belisarius is the nickname I rather arbitrarily gave to the address 0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf on Ethereum mainnet, you can find the origin story for the nickname in the article in front of you. Some links that might be useful: Belisarius decompiled, EtherscanArtThis article’s art was created by MewnCat, based on the concept of bytecode engineering. It’s fit...]]></description>
            <content:encoded><![CDATA[<p><em>Trying to Disambiguate Belisarius’s Obscure Functions</em></p><p><em>For an introduction to this series, see </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/wschwab.eth/CjODHmpDMTbZsAACyFJyFJkB3YakZqH8KUko4AOTMkA"><em>here</em></a><em>. For quick reference, Belisarius is the nickname I rather arbitrarily gave to the address 0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf on Ethereum mainnet, you can find the origin story for the nickname in the article in front of you.</em></p><p><em>Some links that might be useful: </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethervm.io/decompile/0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf"><em>Belisarius decompiled</em></a><em>, </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf"><em>Etherscan</em></a></p><h2 id="h-art" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Art</h2><p>This article’s art was created by <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/MewnCat">MewnCat</a>, based on the concept of bytecode engineering. It’s fittingly titled <em>Bytecode Engineer</em>. The original is animated, but Mirror currently only allows setting a JPG or PNG as the cover art. I’ve uploaded the original to Arweave here:</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://3dhdp6tlqgb6nwkugaal54q5bamdxdzfzpmqdo5ayw3ulqii4gea.arweave.net/2M43-muBg-bZVDAAvvIdCBg7jyXL2QG7oMW3RcEI4Yg?height=2156&amp;width=1080&amp;autoplay=true&amp;loop=true&amp;muted=true">https://3dhdp6tlqgb6nwkugaal54q5bamdxdzfzpmqdo5ayw3ulqii4gea.arweave.net/2M43-muBg-bZVDAAvvIdCBg7jyXL2QG7oMW3RcEI4Yg?height=2156&amp;width=1080&amp;autoplay=true&amp;loop=true&amp;muted=true</a></p><p>I’ve also embedded it below. I’m not able to get looping working for right now, I might update if I do. (Thanks for Mirror for the help getting this embedded, if anyone else is experiencing issues embedding mp4 on Mirror, try adding <code>?display=iframe</code> to the url - if there are already parameters at the end of the url following <code>?</code>, you can put <code>display=iframe</code> after the <code>?</code>, and add a <code>&amp;</code> afterwards).</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://3dhdp6tlqgb6nwkugaal54q5bamdxdzfzpmqdo5ayw3ulqii4gea.arweave.net/2M43-muBg-bZVDAAvvIdCBg7jyXL2QG7oMW3RcEI4Yg?display=iframe&amp;height=1080&amp;width=2156&amp;autoplay=true&amp;loop=true">https://3dhdp6tlqgb6nwkugaal54q5bamdxdzfzpmqdo5ayw3ulqii4gea.arweave.net/2M43-muBg-bZVDAAvvIdCBg7jyXL2QG7oMW3RcEI4Yg?display=iframe&amp;height=1080&amp;width=2156&amp;autoplay=true&amp;loop=true</a></p><p>As with the other articles, this article can be minted as an NFT.</p><h2 id="h-preface" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Preface</h2><p>In <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/wschwab.eth/BNalhR2Z3jsyB24CUAiMKGLbwz411j0QYU-aIkkzaI0">the last chapter</a> we dove into the easier end of decompiling Belisarius. There are two functions we didn’t dive into there, namely the two functions that didn’t have a publicly known selector through <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.4byte.directory/">4byte</a>: <code>0x78e111f6</code> and <code>0xa90e8731</code>. These will be a bit more tricky just because we won’t have the easy cheat of finding what contract they’re from. (We were able to find all of the publicly known selectors in DappSys’s contracts in the last chapter.)</p><p>I started with <code>0x78e111f6</code>, which ended up sending me down a massive rabbit hole.</p><h2 id="h-0x78e111f6" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">0x78e111f6</h2><p>Interestingly enough, if you look through the last few thousand transactions Belisarius has made (hey, don’t judge, it at least strikes me as probably being more healthy than doomscrolling Twitter), you’ll only find calls to the <code>execute</code> function (the <code>execute(address,bytes)</code> version) and the occasional call to <code>0x78111f6</code>. Emboldened by my success finding <code>execute</code> I searched for <code>0x78111f6</code> on Github (which was how I originally placed <code>execute(bytes,bytes)</code>), and while I didn’t find anything on Github, a broader search led me to a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://threadreaderapp.com/thread/1516640065539170304.html">thread</a> written by <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/0xcacti">0xcacti</a> that actually analyzes Belisarius’s use of this function - apparently they were using it for JIT sandwiches at the time the thread was written.</p><p>Analyzing <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/token/0xc36442b4a4522e871399cd717abdd847ab11fe88?a=0xa57Bd00134B2850B2a1c55860c9e9ea100fDd6CF">Etherscan</a>, it looks like <em>all</em> <code>0x78111f6</code> is used for manipulating Uniswap v3 positions. It would be interesting to analyze historically if that’s all this function has ever been used for, but we haven’t done that yet.</p><p>I wasn’t 100% sure where to start, so I ended up trying a few different things. I kept on looking at the decompilation, and was somewhat confident that the first argument was <code>address</code>, and was willing to guess that the next was <code>bytes</code> just by eyeballing the validation. That, and the fact that the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethervm.io/decompile/0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf#func_func_088F">body</a> of the function seemed based around a <code>delegatecall</code> made me willing to guess that this was some variation of <code>execute(address,bytes)</code>, maybe with an additional argument. I poked around GitHub, particularly around DappSys’s contracts, but didn’t find anything.</p><p>While I did keep on looking at the decompilation, and eventually was able to more or less decipher it, another idea I pursued was looking to see if maybe there was another contract with this same function that had verified their code on Etherscan or Sourcify. I am not certain how 4byte works, and it stands to reason to me that it could be possible for there to be verified contracts on either platform that have still not had their selectors uploaded to 4byte. In addition, someone once pointed out another contract to me that they said was “related” to Belisarius. This contract bore numerous similarities to Belisarius, including a <code>0x78e111f6</code> function, which made me theorize that there were probably more. I figured if I could find something this way it would be easier and more accurate than pulling through the decompilation, so I went started figuring out how to find this.</p><h3 id="h-discovering-the-horde" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Discovering the Horde</h3><p>By now we already had an archive node set up with <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/TrueBlocks/trueblocks-core">Trueblocks</a> and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ApeWorX/evm-trace">evm-trace</a>, something we’ll dedicate the next chapter to, so my first thought was to use them, but after some pings on some Discords, the best advice I got was actually to use Google’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://cloud.google.com/blog/products/data-analytics/ethereum-bigquery-public-dataset-smart-contract-analytics">Ethereum BigQuery set</a> for this.</p><p>It has been ages since I wrote SQL, which is the language used for querying, but on the bright side, the dataset provides a set of function selectors, which meant I could query it directly to discover every <code>0x78e111f6</code> contract. After an amazingly frustrating hour or two I managed to put this together:</p><pre data-type="codeBlock" text="SELECT address FROM `bigquery-public-data.crypto_ethereum.contracts` WHERE CONTAINS_SUBSTR(function_sighashes, ‘78e111f6’) AND address != ‘0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf’ LIMIT 1000
"><code>SELECT <span class="hljs-keyword">address</span> FROM `bigquery<span class="hljs-operator">-</span><span class="hljs-keyword">public</span><span class="hljs-operator">-</span>data.crypto_ethereum.contracts` WHERE CONTAINS_SUBSTR(function_sighashes, ‘78e111f6’) AND <span class="hljs-keyword">address</span> <span class="hljs-operator">!</span><span class="hljs-operator">=</span> ‘<span class="hljs-number">0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf</span>’ LIMIT <span class="hljs-number">1000</span>
</code></pre><p>I’ll put this here just in case it helps anyone else trying to familiarize themselves with querying the dataset, and simultaneously in case someone who actually knows what they’re doing can point out a better way to do so.</p><p>I had been worried about getting a huge wave of results, so I put in to limit the query to returning 1000 values, but I needn’t have been worries, as it only yielded me three addresses:</p><pre data-type="codeBlock" text="[{
 &quot;address&quot;: &quot;0xfa103c21ea2df71dfb92b0652f8b1d795e51cdef&quot;
}, {
 &quot;address&quot;: &quot;0x9799b475dec92bd99bbdd943013325c36157f383&quot;
}, {
 &quot;address&quot;: &quot;0x434f179f3f28e2e4476b62562ebe3e2db26b88d7&quot;
}]
"><code><span class="hljs-selector-attr">[{ <span class="hljs-string">"address"</span>: <span class="hljs-string">"0xfa103c21ea2df71dfb92b0652f8b1d795e51cdef"</span>}, { <span class="hljs-string">"address"</span>: <span class="hljs-string">"0x9799b475dec92bd99bbdd943013325c36157f383"</span>}, { <span class="hljs-string">"address"</span>: <span class="hljs-string">"0x434f179f3f28e2e4476b62562ebe3e2db26b88d7"</span>}]</span>
</code></pre><p>The Etherscan links for these three contracts, in order are: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0xfa103c21ea2df71dfb92b0652f8b1d795e51cdef">1</a>, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0x9799b475dec92bd99bbdd943013325c36157f383">2</a>, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0x434f179f3f28e2e4476b62562ebe3e2db26b88d7">3</a>. Number 2 is marked &quot;Fund&quot; by Etherscan, for some reason. None of the three verified their source code. A casual glance sees that two of the three (1 and 2) are prolific (&gt;100k txs), and that they call a function <code>execute</code> quite a bit, which makes one suspect that they are built of very similar code to Belisarius, and will likely be useful to know about.</p><p>After thinking about this for a bit more, something struck me as fishy here. I mentioned before that someone had pointed out another contract similar to Belisarius, and that I had seen that it also had a <code>0x78e111f6</code> function, yet it wasn’t on the list. I went back to BigQuery and saw that I could search all contract bytecode on mainnet. I was worried that it could be possible for the selector to coincidentally appear in bytecode for unrelated reasons, and also because searching the entirety of the contract bytecode would eat up roughly half of the standard BigQuery free trial, but I figured I’d yolo it. It’s pretty much the same query, but I figure I’ll once again put it here to help those newer than me, and to potentially get help from those better versed:</p><pre data-type="codeBlock" text="SELECT address FROM `bigquery-public-data.crypto_ethereum.contracts` WHERE CONTAINS_SUBSTR(bytecode, &apos;78e111f6&apos;) AND address != &apos;0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf&apos; LIMIT 10000
"><code>SELECT <span class="hljs-keyword">address</span> FROM `bigquery<span class="hljs-operator">-</span><span class="hljs-keyword">public</span><span class="hljs-operator">-</span>data.crypto_ethereum.contracts` WHERE CONTAINS_SUBSTR(bytecode, <span class="hljs-string">'78e111f6'</span>) AND <span class="hljs-keyword">address</span> <span class="hljs-operator">!</span><span class="hljs-operator">=</span> <span class="hljs-string">'0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf'</span> LIMIT <span class="hljs-number">10000</span>
</code></pre><p>This gave me an additional 8 addresses (and the three above, I’ve filtered those out by hand):</p><pre data-type="codeBlock" text="[{
 &quot;address&quot;: &quot;0xb00be4839ec2e8ce36959fd41fe37d73d11bebfb&quot;
}, {
 &quot;address&quot;: &quot;0xb00b67377f795b4b4b845a6294ba89477e13ace8&quot;
}, {
 &quot;address&quot;: &quot;0x5050e08626c499411b5d0e0b5af0e83d3fd82edf&quot;
}, {
 &quot;address&quot;: &quot;0xc5ecee6d94f72b6c456e3032f383284cca36b70a&quot;
}, {
 &quot;address&quot;: &quot;0xf2b245f40ed1e8fe30a0d7679535a30d52c5b333&quot;
}, {
 &quot;address&quot;: &quot;0x4cb18386e5d1f34dc6eea834bf3534a970a3f8e7&quot;
}, {
 &quot;address&quot;: &quot;0xa69babef1ca67a37ffaf7a485dfff3382056e78c&quot;
}, {
 &quot;address&quot;: &quot;0xa69babe15c6f4fd07270173ea1d7a19b8c3f8c0b&quot;
}]
"><code><span class="hljs-selector-attr">[{ <span class="hljs-string">"address"</span>: <span class="hljs-string">"0xb00be4839ec2e8ce36959fd41fe37d73d11bebfb"</span>}, { <span class="hljs-string">"address"</span>: <span class="hljs-string">"0xb00b67377f795b4b4b845a6294ba89477e13ace8"</span>}, { <span class="hljs-string">"address"</span>: <span class="hljs-string">"0x5050e08626c499411b5d0e0b5af0e83d3fd82edf"</span>}, { <span class="hljs-string">"address"</span>: <span class="hljs-string">"0xc5ecee6d94f72b6c456e3032f383284cca36b70a"</span>}, { <span class="hljs-string">"address"</span>: <span class="hljs-string">"0xf2b245f40ed1e8fe30a0d7679535a30d52c5b333"</span>}, { <span class="hljs-string">"address"</span>: <span class="hljs-string">"0x4cb18386e5d1f34dc6eea834bf3534a970a3f8e7"</span>}, { <span class="hljs-string">"address"</span>: <span class="hljs-string">"0xa69babef1ca67a37ffaf7a485dfff3382056e78c"</span>}, { <span class="hljs-string">"address"</span>: <span class="hljs-string">"0xa69babe15c6f4fd07270173ea1d7a19b8c3f8c0b"</span>}]</span>
</code></pre><p>These results do include the contract I’d been tipped off about. This does raise the question why they weren’t in the first dataset. My suspicion is something like this: I’d assume that the dataset parses function selectors both by using public databases like 4byte and also by parsing calldata to contracts (since the first four bytes are generally selectors). This means that in the event that a contract has functions that don’t appear in the public databases (like <code>0x78e111f6</code> as of this writing) that perhaps Google doesn’t “see” the function unless it’s been called. That would raise a suspicion that maybe <code>0x78e111f6</code> has only been transacted with in the top 3 (and Belisarius), but not in the other eight. (Or, more pedantically, hasn&apos;t been transacted with directly, since I&apos;d guess they&apos;re scraping functions from the first four bytes of calldata. The difference would be that they <em>could</em> still theoretically have been interacted with, just only indirectly, like if they were only called by a multisig, where the transaction would be from the EOA to the multisig, or otherwise in the middle of another transaction, through multicall or weiroll, etc.) I haven’t tried validating that yet, though.</p><p>There’s a bunch to look at with these addresses, but the most urgent order of business was seeing if any of them verified their source code. They didn’t.</p><p>This discovery, however, did open up a whole new line of research. There are some clear connections between a number of these contracts. One low-hanging point of interest is that many of them (including Belisarius and contracts 1 and 2 above) share a deployer: <code>0x8641df2d7c730a8a24db86693fc39f7a74dd4e9d</code>. It was around now that I decided I should start a naming convention for addresses and entities of interest. Bored of <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://en.wikipedia.org/wiki/Alice_and_Bob#Cast_of_characters">Alice, Bob, and friends</a>, I decided to use a similar alphabetical naming scheme, but somehow taking warrior people from the annals of history sounded better, so henceforth 0x86 became known as <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://en.wikipedia.org/wiki/Artemisia_I_of_Caria">Artemisia</a>. I realized that if I was naming the ubiquitous deployer that I should also be giving our own focal point, 0xa57, a name, and Belisarius was the standout for ‘b’, which is the rather anticlimactic story of why I’ve been calling our contract Belisarius this whole time. (Though, as a side point, if you don’t know who Belisarius is, I highly recommend the chapter about him in Victor Davis Hanson’s <em>The Savior Generals</em>, and while you’re at it, give Henry Wadsworth Longfellow’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.poetry.com/poem/18514/belisarius">poem</a> a read.) Seeing as Artemisia had deployed a number of these contracts, I also checked Trueblocks to see what other contracts Artemisia deployed, I believe there were a total in the thirties. I’ve loosely begun referring to both the <code>0x78e111f6</code>-bearing contracts and all the other contracts Artemisia deployed as The Horde, and it is my assumption that they will all be useful in research down the line, but that will have to be a rabbit hole for another day.</p><p>Trying to research these addresses caused me to learn something interesting: as a part of researching an address, just drop the address in a regular search engine. You may find research that mentions it. Just as an example, the contract Etherscan labeled “Fund” (contract 2 above) has a bit of an online presence:</p><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blog.1inch.io/bancor-network-hack-2020-3c71444fd59d">Bancor Hack Report</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://crocswap.medium.com/impermanent-loss-and-jit-liquidity-in-the-uniswap-eth-usdc-0-3-pool-8fc58c755d7">JIT in Uni v3 ETHUSDC</a></p></li></ul><p>On the other hand, using these addresses for researching <code>0x78e111f6</code> had officially hit a dead end.</p><h3 id="h-calldata-analysis" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Calldata Analysis</h3><p>I thought it might be easier to at least figure out the arguments of the function by taking a look at the calldata <code>0x78e111f6</code> was called with. I started with <code>0xb52668345b575b2baedd2801d13b6bac25fc594ec7e8ed1776f47d1200e3ebb9</code>.</p><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/tx/0xb52668345b575b2baedd2801d13b6bac25fc594ec7e8ed1776f47d1200e3ebb9">Etherscan</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dashboard.tenderly.co/tx/mainnet/0xb52668345b575b2baedd2801d13b6bac25fc594ec7e8ed1776f47d1200e3ebb9/state-diff">Tenderly</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethtx.info/mainnet/0xb52668345b575b2baedd2801d13b6bac25fc594ec7e8ed1776f47d1200e3ebb9/">EthTx</a></p></li></ul><p>Here’s what the raw calldata from that tx looks like:</p><pre data-type="codeBlock" text="0x78e111f6000000000000000000000000b6fb3a8181bf42a89e61420604033439d11a09530000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000018433ef3e6a0000000000000000000000000000000000000000000000000000000062fb6ed900000000000000000000000000000000000000000000000000fe091352dc80f0000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000001857a47ca29a46000000000000000000000000000000000000000000000000001d14a0219e548200000000000000000000000000000000000000000000000000000000000000000070ccc85b0000000000000000000000000000000000000000000000000000000070ccc85b0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000009d97172d0297c0000000000000000000000000000000000000000000000000000000000000
"><code></code></pre><p>Normally I like explaining different ideas that I tried that didn’t work, but I’m going to need to break tradition here. It took me a <em>lot</em> of tries to figure out the best way to represent this data. I’m not sure I got all of it correctly as it stands, but I’ll walk through how I got at least as far as I did.</p><p>The first step is that the first 4 bytes (the first 8 characters after the <code>0x</code>, since the EVM uses 32-byte words) is the function selector of the function being called. After that, we’ll separate the next three words (32 bytes) each onto it’s own line.</p><pre data-type="codeBlock" text="0x78e111f6
    000000000000000000000000b6fb3a8181bf42a89e61420604033439d11a0953
    0000000000000000000000000000000000000000000000000000000000000040
    0000000000000000000000000000000000000000000000000000000000000184
"><code>0x78e111f6
<span class="hljs-code">    000000000000000000000000b6fb3a8181bf42a89e61420604033439d11a0953
    0000000000000000000000000000000000000000000000000000000000000040
    0000000000000000000000000000000000000000000000000000000000000184
</span></code></pre><p>Looking at the <code>delegatecall</code>s made in the transaction, we can see that the first word is the address of the strategy contract being called by Belisarius. This is more or less confirmation that the <code>0x78e111f6</code>’s first argument is <code>address</code>. The others are simple hexadecimal values, hard to tell what they are quite yet - though the first, <code>0x40</code>, is 64 when translated into decimal, which in the world of powers of 2 (and 32-byte words), is a suspiciously convenient number, which I think makes it fair to have a suspicion that it’s a number (as opposed to something like a string or other datatype).</p><p>While splitting into 32-byte lines is a simple tactic, it’s surprisingly useful. If you’d just eyeball the calldata, it’s easy to miss that lone 4 in a sea of zeroes, let alone see that it’s actually 40 instead of 4. In addition, it would be easy to think that the 184 keeps on going, since it’s followed by nonzero hexes (<code>33ef3e6a</code>) too. That itself is a bit interesting, though - as you can see in the first lines, usually arguments are left-padded, meaning that for example, the address gets enough zeroes added to the beginning of the line to pad the address to 32 bytes. If that’s the case, how come the fourth line <em>starts</em> with <code>33ef3e6a</code> and then has zeros after it (right-padded)? On the other hand, looking at <code>33ef3e6a</code>, it looks like a function selector itself, and looking at the strategy contract’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethervm.io/decompile/0xb6fb3a8181bf42a89e61420604033439d11a0953">decompilation</a>, we can see that it has a function with that selector. If we make a leap of faith for a second and say that the calldata starting <code>33ef3e6a</code> starts a second call nested in the first, a lot of the calldata falls into place. First, let’s break it up:</p><pre data-type="codeBlock" text="[1]  0x78e111f6
[2]      000000000000000000000000b6fb3a8181bf42a89e61420604033439d11a0953
[3]      0000000000000000000000000000000000000000000000000000000000000040
[4]      0000000000000000000000000000000000000000000000000000000000000184
[5]      33ef3e6a
[6]          0000000000000000000000000000000000000000000000000000000062fb6ed9
[7]          00000000000000000000000000000000000000000000000000fe091352dc80f0
[8]          000000000000000000000000000000000000000000000000000000000000007f
[9]          00000000000000000000000056178a0d5f301baf6cf3e1cd53d9863437345bf9
[10]         000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
[11]         000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
[12]         00000000000000000000000000000000000000001857a47ca29a460000000000
[13]         00000000000000000000000000000000000000001d14a0219e54820000000000
[14]         0000000000000000000000000000000000000000000000000000000070ccc85b
[15]         0000000000000000000000000000000000000000000000000000000070ccc85b
[16]         0000000000000000000000000000000000000000000000000de0b6b3a7640000
[17]         00000000000000000000000000000000000000000000009d97172d0297c00000
[18]         00000000000000000000000000000000000000000000000000000000
"><code>[<span class="hljs-meta">1</span>]  <span class="hljs-number">0x78e111f6</span>
[<span class="hljs-meta">2</span>]      <span class="hljs-number">000000000000000000000000b</span>6fb3a8181bf42a89e61420604033439d11a0953
[<span class="hljs-meta">3</span>]      <span class="hljs-number">0000000000000000000000000000000000000000000000000000000000000040</span>
[<span class="hljs-meta">4</span>]      <span class="hljs-number">0000000000000000000000000000000000000000000000000000000000000184</span>
[<span class="hljs-meta">5</span>]      <span class="hljs-number">33</span>ef3e6a
[<span class="hljs-meta">6</span>]          <span class="hljs-number">0000000000000000000000000000000000000000000000000000000062f</span>b6ed9
[<span class="hljs-meta">7</span>]          <span class="hljs-number">00000000000000000000000000000000000000000000000000f</span>e091352dc80f0
[<span class="hljs-meta">8</span>]          <span class="hljs-number">000000000000000000000000000000000000000000000000000000000000007f</span>
[<span class="hljs-meta">9</span>]          <span class="hljs-number">00000000000000000000000056178</span>a0d5f301baf6cf3e1cd53d9863437345bf9
[<span class="hljs-meta">10</span>]         <span class="hljs-number">000000000000000000000000</span>c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
[<span class="hljs-meta">11</span>]         <span class="hljs-number">000000000000000000000000</span>a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
[<span class="hljs-meta">12</span>]         <span class="hljs-number">00000000000000000000000000000000000000001857</span>a47ca29a460000000000
[<span class="hljs-meta">13</span>]         <span class="hljs-number">00000000000000000000000000000000000000001</span>d14a0219e54820000000000
[<span class="hljs-meta">14</span>]         <span class="hljs-number">0000000000000000000000000000000000000000000000000000000070</span>ccc85b
[<span class="hljs-meta">15</span>]         <span class="hljs-number">0000000000000000000000000000000000000000000000000000000070</span>ccc85b
[<span class="hljs-meta">16</span>]         <span class="hljs-number">0000000000000000000000000000000000000000000000000</span>de0b6b3a7640000
[<span class="hljs-meta">17</span>]         <span class="hljs-number">00000000000000000000000000000000000000000000009</span>d97172d0297c00000
[<span class="hljs-meta">18</span>]         <span class="hljs-number">00000000000000000000000000000000000000000000000000000000</span>
</code></pre><p>(You may need to copy-paste that into a text editor, depending on how usefully it’s formatted by Mirror.)</p><p>There is something that may look a little bit weird here, namely that the calldata does not end neatly at the end of its line. I plan on getting back to that later. By breaking the calldata up like this there are some things we can get even from a first glance - lines 9-11 look like addresses, and it’s very reasonable to assume that they are, being that the first is the address that received the funds from the transaction (and seems to be a common recipient of Belisarius’s transactions in general, making it likely a member of The Horde), followed by the addresses of the two tokens comprising the Uniswap pool being interacted with: WETH and USDC. Lines 6 and the repeated value in lines 14-15 are the right size to be a function selector, but I did not find a matching selector in the databases nor in the strategy contract being <code>delegatecall</code>ed by Belisarius in the transaction.</p><p>This does leave the question of why and how there’s a call nested in the call, but if you think about it for a minute, the truth is that this closely resembles what we know of <code>execute(address,bytes)</code>. If we’re willing to continue with that thought process, we would expect the payload to call to the strategy contract with to be a bytes array (<code>bytes</code> in Solidity). The payload starts with the function selector, in this case <code>33ef3e6a</code>, so that leaves us to figure out what lines 2 (<code>0x40</code>) and 3 (<code>0x184</code>) are.</p><p>I’ll skip ahead to the answer here, which is something you likely have already figured out if you’re familiar with array encoding. Starting at the beginning, <code>bytes</code> is a kind of array under the hood. It stores an arbitrary amount of, well, bytes. How does the EVM know what is a member of an array, and what is a value outside of it? For example, let’s say you’re making a call to a function that takes <code>(bytes32[], bytes32)</code> as arguments, how would the EVM know if a particular 32-byte word is in the array or the argument afterwards? The answer is that there are two additional pieces of information that get encoded with an array: the <em>offset</em> and the <em>number of elements</em>. I’m not sure I understood the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.soliditylang.org/en/latest/abi-spec.html#argument-encoding">spec</a> entirely, so I’ll explain as best as I can, and please dyor to see if I’m right or not. The offset simply tells us how far into the calldata or bytecode to look to see where the number of elements are (which will then be followed by the actual data). (Even though we’re talking about an array with a potentially dynamic length in the example - <code>bytes32[]</code> - remember, calldata is immutable, so when the call is being made it’s treated like a fixed-length array. If you’re really interested in knowing how dynamic-length arrays are encoded, that’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.soliditylang.org/en/latest/abi-spec.html#use-of-dynamic-types">here</a> in the spec.)</p><p>Looking at our calldata, line 2’s value is <code>0x40</code> in hex, or 64 in decimal. If this is an offset, it would mean the number of elements should start 64 bytes in, or in other words, at the beginning of line 3. Line 3’s value is <code>0x184</code>, or 388 in decimal. If you count that out (starting from the beginning of line 5), that would take us precisely to the end of line 17, which would seem convenient enough to basically serve as confirmation that we’re correct in our assumption and the way we broke things up above.</p><p>It also means that at least as far as we can tell, <code>0x78e111f6</code>’s args are <code>(address,bytes)</code>, which would mean that it is <em>not</em> named <code>execute</code>, since we’ve already got an <code>execute(bytes,bytes)</code>. I did try a number of variants using Cast, like <code>execute0</code>, <code>execute_</code>, and <code>x</code>, but to no avail.</p><p>Having a stronger idea of what the arguments were, I felt it was time to look at the decompilation more closely.</p><p>Before we do that, let’s try to clear up one last potential mystery. Doesn’t it seem strange that the calldata on line 18 doesn’t have 64 characters? (In case you don’t feel like counting, it’s 56 zeros, or 28 bytes.) Isn’t the encoding always in 32-byte words? I fell down a bit of a rabbit hole and discovered that some MEV bots apparently add some non-ABI-encoded data in their calls, as it can still be accessed through <code>msg.data</code>, but there’s an even simpler answer. If you look at the way we broke things up before, both line 1 and 5 have only 4 bytes. Line 1 is the function selector for the call, so it really is an exception to the 32-byte word rule, but line 5, even though it’ll be used as a function selector in another call, is just a part of a bytes array. The bytes array itself is not cleanly divisible by 32 bytes, so it gets some additional padding. If you look at the calldata as a whole (well, excluding line 1), the entirety is indeed divisible by 32.</p><h3 id="h-back-to-the-bytecode" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Back to the Bytecode</h3><p>Let’s go through EtherVM’s decompilation of <code>0x78e111f6</code> more thoroughly. Just looking through the code, we can see the decompilation of the function is divided into three parts: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethervm.io/decompile/0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf#dispatch_78e111f6">the initial dispatch</a>, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethervm.io/decompile/0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf#func_func_0302">func_0302</a>, and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethervm.io/decompile/0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf#func_func_088F">func_088F</a>.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/60a35462241d329d6d92da3d944a146de9e495d78409c48db868646125800153.png" alt="the decompilation continues after this, but the rest isn&apos;t relevant for us afaict" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">the decompilation continues after this, but the rest isn&apos;t relevant for us afaict</figcaption></figure><p>The initial dispatch first gets the size of the calldata minus the selector by taking the length of the calldata and subtracting 4 from it (for the selector). If the calldata is less than 64 bytes, the call reverts. Now that we know that there are two arguments to the function, this makes sense - 64 bytes is the minimum size for two arguments (a 32-byte word for each). It then jumps to what it calls <code>func_0302</code></p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/0dc3f572671c28add442273b6e1ecb7676d2cca19d41b5a1474394842603663e.png" alt="func_0302" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">func_0302</figcaption></figure><p>If you look at the image above, you’ll see that <code>arg0</code> at the time this function is called is 4, and <code>arg1</code> is the size of the calldata minus 4 (so the length of the data without the selector). If I’m reading correctly, the first <code>if</code> should be checking the line with the offset for the bytes array. I assume that the check is based on some part of the ABI spec (probably the max size for calldata), but am too lazy to find out. If that is the case, the next <code>if</code> makes sure that the offset is somewhere inside the calldata; if the offset is a higher number than the length of the calldata, something is wrong, and it just reverts.</p><p>Assuming we’re still reading right, <code>temp3</code> should be the word the offset points to, which should be the number of bytes in the <code>bytes</code> argument. I’m assuming that <code>0x100000000</code> is still the upper bound on calldata size, and if the number of bytes the calldata says is in the array is bigger than that, the validation fails and it reverts. <code>temp5</code> would then be the same thing, which is then used to pull the data of the bytes array into memory. Then <code>func_088F</code> is called with the address as the first arg. The second arg, as far as I can tell, is actually just 32 bytes of zeroes, since when that variable is set by reading from memory there shouldn’t be any memory stored there, but I’m not sure about that.</p><p>(One thing that might be becoming clear is that either I’m not very good at reading decompilation, or that the compiler seems to do a number of either redundant or otherwise weird operations. I’m feeling like I might have finally nerded out enough to appreciate <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/figs999/Ethereum/blob/master/Solc.aComedyInOneAct">this</a> famous classic a bit more, though nowhere near that level of proficiency.)</p><p>Looking back, that would make this block largely data type validation, and some preparatory memory operations. I’ve started noticing that this seems to be a general rule with EtherVM; first, in the dispatch, all it does is check that there’s enough data to support the number of arguments. Then it jumps, and that jump is to some basic data type validation and memory prep, then it jumps again and that’s where the main logic is. I don’t think that this is an ironclad rule, but you might find it useful in your own journeys.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/300c210dd6b87ffc66fb176ab12f925a7d54c69306abb1177a02977ac64ffa39.png" alt="I can&apos;t fit the whole delegatecall in the screenshot" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">I can&apos;t fit the whole delegatecall in the screenshot</figcaption></figure><p>The first <code>if</code> in <code>func_088F</code> checks if <code>msg.sender</code> is a <code>ward</code> or not, and reverts if not. After that we hop into a <code>delegatecall</code>. Both <code>call</code> and <code>delegatecall</code> return two variables - a bool indicating if the call was successful or not, and the data returned by the call. A variable is set to store the bool (so the function can revert if the <code>delegatecall</code> wasn’t successful), but doesn’t bother committing the data to memory in this line - it’ll use <code>returndata</code> for that.</p><p>Since the <code>delegatecall</code> didn’t fit in the screenshot, here it is:</p><pre data-type="codeBlock" text="temp1, memory[0x00:0x00] = address(arg0).delegatecall.gas(msg.gas)(memory[temp0 + 0x20:temp0 + 0x20 + memory[temp0:temp0 + 0x20]]);
"><code>temp1, <span class="hljs-keyword">memory</span>[<span class="hljs-number">0x00</span>:<span class="hljs-number">0x00</span>] <span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(arg0).<span class="hljs-built_in">delegatecall</span>.<span class="hljs-built_in">gas</span>(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">gas</span>)(<span class="hljs-keyword">memory</span>[temp0 <span class="hljs-operator">+</span> <span class="hljs-number">0x20</span>:temp0 <span class="hljs-operator">+</span> <span class="hljs-number">0x20</span> <span class="hljs-operator">+</span> <span class="hljs-keyword">memory</span>[temp0:temp0 <span class="hljs-operator">+</span> <span class="hljs-number">0x20</span>]]);
</code></pre><p>That should be more or less what we expect. It <code>delegatecall</code>s the address that was passed in, and supplies the <code>bytes</code> arg from memory. The next chunk pulls the <code>returndata</code> into memory, and returns it if the call failed. If the call failed, the returned data is the error message, so this allows the function to return an error message from a failed <code>delegatecall</code>.</p><p>(It does seem like there are still some more unsolved mysteries here, since <code>func_088F</code> returns something, but I haven’t quite figured that out, and it doesn’t seem terribly relevant either.)</p><p>At this point, we seem to have a fairly good idea of what <code>0x78e111f6</code> does - it takes an address and a payload, and <code>delegatecall</code>s the address with the payload. The thing is, that’s exactly what <code>execute(address,bytes)</code> does, no? Why does the contract need both? I went back and started comparing the decompilation of the two functions, and realized that they are almost identical. There’s only one difference (as far as I can tell), namely that <code>0x78e111f6</code> bubbles up the error message on a failed <code>delegatecall</code> whereas <code>execute(address,bytes)</code> does not.</p><p>I’m fairly certain that this is the difference between them. Out of curiosity, I looked at the code in ds-proxy again, and while the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/dapphub/ds-proxy/blob/master/src/proxy.sol">current implementation</a> of <code>execute(address,bytes)</code> does bubble up the errors, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/dapphub/ds-proxy/blob/9ccaf3d04d960a20ffbcb57041e0867d9e55b4f9/src/proxy.sol#L74-L77">once upon a time</a> it did not. So Belisarius’s <code>execute(address,bytes)</code> is actually taken from the older version of ds-proxy, while <code>0x78e111f6</code> is the newer. I tried some selector brute forces from that (<code>executeNew</code>, <code>executeWithErr</code>, <code>executeErr</code>, etc), but still to no avail.</p><p>Interestingly, like we originally pointed out by way of 0xcacti’s thread, Belisarius uses <code>0x78e111f6</code> as the second leg of Uniswap v3 JIT attacks. This implies something, I would suspect the most obvious guess is that there is some special need to be able to see error messages there. I’m not an expert with Uniswap v3 at all, so I don’t know why that would be. One other idea that occurred to me was that it simply might make detecting the attacks harder if they come from two separate functions.</p><h2 id="h-0xa90e8731" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"><code>0xa90e8731</code></h2><p>That brings us to the last of Belisarius’s functions for us to unravel.</p><p>Here I started with the decompilation. I’ve been getting comfortable enough with it that I figured I’d get what details I could out of it before looking for code in DappSys and casting wider nets in Github.</p><p>The validation in the initial dispatch looks for 64 bytes of data, so it seems that the function takes two arguments. It then sends off to <code>func_04A7</code>. <code>func_04A7</code> is quite large, so one of the first things I did was try to find which function it in turn sent off to, since most functions I’ve seen in EtherVM break into three parts, as mentioned above. Interestingly enough, the bottom of the function doesn’t send to another function - it’s a bunch of nested if/else conditions and jump destinations, which at least instinctively looks to me something like a for-loop likely would. Scrolling up, the only line I could find that would jump outside <code>func_04A7</code> was:</p><pre data-type="codeBlock" text="return func_088F(var3, var4);
"><code><span class="hljs-keyword">return</span> func_088F(var3, var4);
</code></pre><p>You may remember <code>func_088F</code> from the previous section - it’s the main logic of <code>0x78e111f6</code>. This piqued my curiosity. In ds-proxy, <code>execute(bytes,bytes)</code> makes a call to <code>execute(address,bytes)</code> at the end of it. If <code>0x78e111f6</code> is the newer version of <code>execute(address,bytes)</code> that includes error bubbling, a good initial hypothesis would be that <code>0xa90e8731</code> is a version of <code>execute(bytes,bytes)</code> that calls it. Looking at the code of <code>execute(bytes,bytes)</code>, we see that it calls two other functions, <code>read</code> and <code>write</code>:</p><pre data-type="codeBlock" text="target = cache.read(_code);
    if (target == address(0)) {
        // deploy contract &amp; store its address in cache
        target = cache.write(_code);
    }
"><code>target <span class="hljs-operator">=</span> cache.read(_code);
    <span class="hljs-keyword">if</span> (target <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0</span>)) {
        <span class="hljs-comment">// deploy contract &#x26; store its address in cache</span>
        target <span class="hljs-operator">=</span> cache.write(_code);
    }
</code></pre><p>We should be able to find these selectors (read: <code>0x8bf4515c</code>, write: <code>0x7ed0c3b2</code>) in the code of <code>0xa90e8731</code> if our hypothesis is correct. Sure enough, they’re both there.</p><p>Another quick check would be checking the decompilation of <code>execute(bytes,bytes)</code> against <code>func_04A7</code>. Just eyeballing the two is enough to see that they aren’t the exact same, but are indeed very similar. One particular point of interest is:</p><pre data-type="codeBlock" text="func_0603(var2, var3); 
return;
"><code>func_0603(var2, var3)<span class="hljs-comment">; </span>
return<span class="hljs-comment">;</span>
</code></pre><p><code>func_0603</code> is the main logic for <code>execute(address,bytes)</code>, so this is the analog to where <code>0xa90e8731</code> sends off to <code>func_088F</code>, if our theory is correct. The big difference is that <code>func_04A7</code> returned the result of <code>func_088F</code>, implying a return value, whereas <code>execute</code> is not returning a value from <code>func_0603</code>, but rather returning the next line. For me, this makes sense, since <code>func_088F</code> can return an error message, but <code>func_0603</code> will not.</p><p>This is all enough for me to conclude that <code>0xa90e8731</code> is to <code>0x78e111f6</code> as <code>execute(bytes,bytes)</code> is to <code>execute(address,bytes)</code> in Belisarius, at least until proven otherwise.</p><h2 id="h-well-why-not" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Well Why Not</h2><p>The final cherry on top would have been getting the function names for <code>0x78e111f6</code> and <code>0xa90e8731</code>. In the name of Research, I decided I’d reach out to Artemisia and Belisarius on-chain, and see if maybe they’d be willing to fill me in. For those who haven’t heard of it, you can essentially send a message to an address on-chain by sending an otherwise empty transaction to the address and encoding your message in UTF-8 in the data field. (I’m planning on making a different message to Belisarius the topic of an Interlude.)</p><p>I used Etherscan’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/idm">IDM</a> tool to send the messages. If you’re interested, these are the transactions: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/tx/0x8a546439dd3800669b242d20c3b3a10f3a08f296433507209e916ee0d19aba7b">Artemisia</a>, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/tx/0x37926dd0f4c1f337923df3cf8e9c2af5ff7ca455320f0aa77c439ad8363258b8">Belisarius</a>. If you’d like to follow along in IDM, you can use these links: <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/idm-chat?addresses=0x8641df2d7c730a8a24db86693fc39f7a74dd4e9d,0x7bfaf4c59aa4f011672b8e77789e1eb41abd654d&amp;title=Artemisia">Artemisia</a>, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/idm-chat?addresses=0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf,0x7bfaf4c59aa4f011672b8e77789e1eb41abd654d&amp;title=Belisarius">Belisarius</a>. Even if they send a return message from a different address, it should still show up there.</p><p>On a side note, even though contracts don’t have built-in capabilities to make an arbitrary call, which should prohibit messaging if they don’t have a specific function for it, Belisarius should be able to respond. While I suspect that calling <code>execute(address,bytes)</code> with my address and the message UTF-8 encoded as the second argument would revert - I assume it would try <code>delegatecall</code>ing into my address, which is an EOA, and fail, there is another way. An operator (or anyone, really) could deploy a contract with a function something like this:</p><pre data-type="codeBlock" text="function chat(address target, bytes message) external {
  (bool success, bytes memory data) = target.call(message);
  assert(success, data);
}
"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">chat</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> target, <span class="hljs-keyword">bytes</span> message</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> </span>{
  (<span class="hljs-keyword">bool</span> success, <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> data) <span class="hljs-operator">=</span> target.<span class="hljs-built_in">call</span>(message);
  <span class="hljs-built_in">assert</span>(success, data);
}
</code></pre><p>Then, Belisarius could <code>execute(address,bytes)</code> into that contract with the call to <code>chat</code> encoded as the second argument. That would <code>delegatecall</code> the <code>chat</code> function, making it look like Belisarius sent the message. That all being said, I wouldn’t expect Belisarius to respond directly. In fact, I’m none to certain that I’ll receive a response at all. But if I do, I expect that it’ll be Artemisia or one of the other operators.</p><h2 id="h-conclusion" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Conclusion</h2><p>It seems fair to conclude that we have a fair idea of everything that&apos;s happening in the Belisarius contract at this point. Something that is of interest is that this seems more or less unnecessary for understanding Belisarius&apos;s activities. All you need to know is that Belisarius deploys other contracts with more granular logic and uses those to execute transactions, but the actual details seem largely irrelevant. As a complete dilettante who&apos;s just interested in a good time (with my own bizarre definitions of what that means), I still consider it time well spent.</p><p>Something that we do gain from having a better understanding of the contract is a better idea of what can be researched. Understanding the `rely`, `deny`, and `wards` functions means a better understanding of where we can look to understand operators of the contract over time. Understanding the various `execute` functions means we can understand that there&apos;s a whole realm of research in discovering these strategy contracts and understanding them.</p><p>As mentioned before, this roughly completes an analysis of all of the functions on Belisarius. I’ve put together a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://gist.github.com/wschwab/e5794a8c3a25a98dcd8dfd54a69c4baa">Gist</a> with an approximation of the code.</p><p>We also learnt that there is a whole cadre of Belisarius-like contracts out there.</p><p>The next steps will involve needing to be able to scrape data from the chain. For us, that meant setting up an archive node in the cloud. I haven&apos;t seen a good resource on that, so decided we&apos;d take a detour from analysis to detail getting that set up, and then we&apos;ll get into the data we found, and what it might mean.</p><p>I say next steps, but we’ve been working at this already. We have some initial data, I’ve got a fren working on some visualizations, and we’re trying to figure out how to take this further. I’ve also started on a couple of Interludes, pieces that are more narrative around some stories, real or imagines, that have come from this research.</p><p>As always, if you&apos;re interested in contributing, or otherwise have comments or observations you&apos;d like to add, we&apos;d love to hear from you, anon.</p>]]></content:encoded>
            <author>wschwab@newsletter.paragraph.com (Will Schwab)</author>
            <enclosure url="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/c361d1c30359d3860f2110d06bbcee16a3a826f9326334ea70da64f0521083dd.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Belisarius and the Horde Chapter 0: The Portal]]></title>
            <link>https://paragraph.com/@wschwab/belisarius-and-the-horde-chapter-0-the-portal</link>
            <guid>FrJXa6mOGIETTODYDJVY</guid>
            <pubDate>Thu, 27 Oct 2022 14:46:01 GMT</pubDate>
            <description><![CDATA[An Introduction to a Tale of Obsession, Side Quests, and Open LedgersIntroductionI don’t remember for sure how it happened, but I think I first heard of 0xa57b (the address that at some point I would name Belisarius) from a fairly innocent Crypto Twitter interaction in which some members of the ecosystem made comments about offering prayers and sacrifices to 0xa57b whenever they made a transaction. As an enjoyer of Cthulhu-like figures in all aspects of life, I likely just filed the tidbit aw...]]></description>
            <content:encoded><![CDATA[<p><em>An Introduction to a Tale of Obsession, Side Quests, and Open Ledgers</em></p><h2 id="h-introduction" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Introduction</h2><p>I don’t remember for sure how it happened, but I think I first heard of 0xa57b (the address that at some point I would name Belisarius) from a fairly innocent Crypto Twitter interaction in which some members of the ecosystem made comments about offering prayers and sacrifices to 0xa57b whenever they made a transaction. As an enjoyer of Cthulhu-like figures in all aspects of life, I likely just filed the tidbit away mentally at the time. As time would go by, though, I would slowly discover more details. Unlike many little hobbies of mine, this one would accumulate slowly. I embarked on one side quest after another until I realized that it wasn’t just a series of tangents, but a campaign of its own.</p><p>Belisarius/0xa57b is baptized as “MEV Bot” on Etherscan, one of many addresses to share the moniker. MEV has long been referred to as a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.paradigm.xyz/2020/08/ethereum-is-a-dark-forest">dark</a> <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://samczsun.com/escaping-the-dark-forest/">forest</a>, or in more simple terms, a field in which clearly discerning the participants is difficult. (That isn’t the full definition of a dark forest as it’s usually used, I know, but is sufficient for right here and right now in my humble opinion.) However, the nature of blockchains is such that at least some of the information should always be there, right in front of our eyes, immutably inscribed on the public ledger for eternity. Even if it may be difficult to predict where the spirits of MEV may strike next, at the very least it should be possible to see post facto where they already did strike, and in the presence of sufficient data, reconstruct an idea of strategy. Have I mentioned that Belisarius has, as of this writing, already transacted more than 3.4 million times?</p><p>(Another interesting tidbit about Belisarius is that it’s old, at least by my standards. It’s called “MEV Bot” on <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf">Etherscan</a>, but as far as I can tell, it actually predates the term MEV. You can check on Etherscan, it was <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/tx/0x0d8fc644c8178a352cd39aed1c3ae58434e422390c96f182b3fd68c53ec070e2">deployed</a> in block 7,445,835 on March 26, 2019, and at least the first reference I’m aware of to MEV was Karl Floersch at EthCC in 2020 (unless I totally made that up, I went looking for the talk but didn’t find it), a bit more than a year later.)</p><p>Those in the field seem to agree that most participants try to obfuscate themselves to some degree. The reasoning seems simple: if you have a winning value-extraction strategy, you stand to gain the most the fewer people that know about that strategy. There is a finite amount of money that the strategy will work for, and the more people participating, the thinner that number is stretched. As a result it can be hard to find information about how to enter the field, and I have even seen it said that sometimes deliberate misinformation is spread. But the chain doesn’t usually lie, anon.</p><p>I started asking myself what would be if we could cast light on these dark environs.</p><p>One thing that seems consistent is that successfully partaking of the spoils of war requires persistence and determination. I will likely never fulfill these criteria. If I ever played games, I was probably the kind of person who spent their time constructing Final Fantasy parties of the members I thought the main character would probably take with, a long trail of unfinished attempts behind me. (Maybe. I can’t confirm.) I am a dreamer and a tinkerer. But what if that dream could conjure the preimage of the hidden? Could we level the playing field even more?</p><p>Perhaps I shall become Light, revealer of worlds.</p><p>I would be remiss if I omitted the amount of help I’ve gotten along the way. I switch between I/me and we/us frequently since a lot of the time someone was helping me out along the way. Not only is Ethereum an open ledger, but also a very open community, and my experience has always been that there are a lot of people out there who are happy to help. I often do not refer to those who have helped by name. An assumption I’m making is that not everyone wants their name publicized all the time. If you see something here that you helped with and are interested in attribution, please let me know and I’ll rectify it.</p><h2 id="h-the-vast-toolkit" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The Vast Toolkit</h2><p>I had not realized at the inception of this journey how many different skill sets would be needed for it. In addition to the fruits of the labor, which at this point are largely nonexistent anyway, the actual labor itself may be of use to those looking at scenarios where the same skills are needed. We started with reverse engineering raw bytecode, moved on to bytecode decoding, engaged in historical analysis, dabbled in forensics, and that’s where we are as of now, though the future is quite open to more too.</p><p>I make no claims to be an expert of any of these methods, and in fact, will try to include where I stumbled and blundered along the way. This is not meant to be a textbook of successes, rather a cypherpunk noir tale of late nights in rooms dimly lit by the glow of monitors, of stumbling through raw hexadecimal streams, and what dark detective tale is not enriched by seeing the blunders along the way?</p><p>In that sense, these writings also serve as a signal, a call to anyone who sees more and further than I, to offer their wisdom to the story, to piece the puzzle together in ways I could not. Please do reach out and illuminate that which I did not.</p><h3 id="h-a-portal" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">A Portal</h3><p>This post serves as an introduction to our story, and a portal to the chapters of it. As such, it is my hope that it is updated over time, since this caper is long from solved. My suspicion now is that the chapters will not need to be read sequentially, though it might add some context. Different chapters are likely to emphasize different skills or tools, so from a technical perspective, they are likely to have standalone value. I certainly have not written myself into a wall yet, and in fact have not even written all the chapters described here. As such, I hope that this list will be added to over time, and that items that appear here as ideas, and yet-to-be-published writings will be made into live links.</p><p><strong><em>Already written:</em></strong></p><h3 id="h-cracking-the-contract" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Cracking the Contract</h3><p>Chapter 1 deals with the initial parts of trying to decompile Belisarius, focusing on the functions with selectors already in <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://4byte.directory">4byte</a> at the time of the writing.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/wschwab.eth/BNalhR2Z3jsyB24CUAiMKGLbwz411j0QYU-aIkkzaI0">https://mirror.xyz/wschwab.eth/BNalhR2Z3jsyB24CUAiMKGLbwz411j0QYU-aIkkzaI0</a></p><h3 id="h-the-contract-and-the-calldata" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">The Contract and the Calldata</h3><p>Chapter 2 continues the decompilation, focusing on the two functions with selectors not in the public databases (<code>0x78e111f6</code> and <code>0xa90e8731</code>). In addition to looking at the decompilation more closely, we also start looking at raw calldata to understand these functions better.</p><p>It&apos;s likely worth pointing out here already that decompiling Belisarius is really not all that relevant to MEV or getting any kind of understanding of Belisarius&apos;s operations. At the same time, it is a nice side quest on its own, at least in my opinion, and I figure it might be a useful resource to have an amateur at the craft of contract reverse engineering detail what diving into such an endeavor was like.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/wschwab.eth/cB8O2y3BqKublvhEhgsg7iX1B-Aee_cGCBZ5K6NWkFA">https://mirror.xyz/wschwab.eth/cB8O2y3BqKublvhEhgsg7iX1B-Aee_cGCBZ5K6NWkFA</a></p><p><strong><em>Currently being written:</em></strong></p><h3 id="h-rigging" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Rigging</h3><p>Chapter 3 is a bit of a break from work directly on Belisarius, and instead details the setup we set up as we started on full-fledged analytics. This includes setting up a server, provisioning it with clients and Trueblocks, discovering how to back up datasets, and trying to build a pipeline.</p><p><strong><em>Some ideas for future chapters:</em></strong></p><h3 id="h-commanders-of-the-horde" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Commanders of the Horde</h3><p>A more detailed analysis. We begin by looking at Belisarius’s operators, and how some of the inquiries in Chapter 2 lead to discovering a whole horde of MEV bot contracts.</p><h3 id="h-an-army-of-strategies" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">An Army of Strategies</h3><p>Continuing with analysis, shifting focus from the operators to the strategy contracts that Belisarius makes use of. I suspect that we&apos;ll need to decompile some of the more popular strategy contracts, though I don&apos;t know if we&apos;ll spend as much time on it this time around.</p><p>I wouldn&apos;t take the plans too seriously, though. If there&apos;s one thing that&apos;s likely, it&apos;s that new information and discoveries lead to new directions. New ideas with the old happen over time too. I&apos;m already considering putting in interludes that are more story-like. I&apos;ve got one so far, and I hope to unearth more stories from the data as time goes by.</p><h2 id="h-data" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Data</h2><p>There are various pieces of data we’ve put together over the months we’ve been working on this. We would like for these to be open to the public, but also are aware that there is some volatility in the data due to my own amateur nature. As such, I’ll link to what we have now, with the caveat that some of it is likely to change. As time goes by, I hope to have more confidence and to have things take more shape, and perhaps the contents and links in this section will change.</p><ul><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://gist.github.com/wschwab/e5794a8c3a25a98dcd8dfd54a69c4baa">A loose recreation of Belisarius’s contract</a> - coming to these conclusions is the topic of the first two chapters, and I almost feel like it’s spoilers to see it before seeing those, but I should probably just get over myself and link it directly.</p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.kaggle.com/datasets/wschwab/0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf">Kaggle dataset</a> - I hope we’ll explain this in more detail in Chapter 3 and beyond, but the quick explanation would be that this is a dataset of all txs, logs/events, and traces from Belisarius, updated weekly. There are also some helper datasets there, like a list of any EOA that’s interacted with Belisarius, sorted by how many times they interacted. The set is generated using <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/TrueBlocks/trueblocks-core">Trueblocks</a>, and I hope to cover in detail how we&apos;re using Trueblocks to get this data.</p></li></ul><h2 id="h-art" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Art</h2><p>One of the joys of publishing on Mirror is the built-in ability to tokenize the works. This gave me the idea of asking some artists if they would be interested in making artwork for the articles, since I figure that owning an NFT of a blog post with cool artwork is much cooler than owning an NFT of a blog post without. The goal is not really to rake in mad stacks of cash, and as such the plan is to keep the NFTs as plentiful as Mirror allows, and cheap. On the other hand, I&apos;m only a part of the equation, so whatever supply/price there is for any given chapter will be a discussion between us.</p><p>This article&apos;s art was created by <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/mojibake_biz">Mojibake</a>, who created it based on the idea of a dark spirit stalking the chain. The image is both cropped and compressed to work with Mirror, if you’d like to view the original, see <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://e6wnvk5m3wa7tbrwur5f6wovnltig5kko7zcwzf3owvoagx5m7ra.arweave.net/J6zaq6zdgfmGNqR6X1nVauaDdUp38itku3Wq4Br9Z-I">here</a>. (Thanks to zkDoof for the help with uploading it.)</p>]]></content:encoded>
            <author>wschwab@newsletter.paragraph.com (Will Schwab)</author>
            <enclosure url="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/84bcfa34f0015d80dd3344f230812db44df176a1d8c71a1d64d0d388a436f673.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Belisarius and the Horde Chapter 1: Cracking the Contract]]></title>
            <link>https://paragraph.com/@wschwab/belisarius-and-the-horde-chapter-1-cracking-the-contract</link>
            <guid>BttQzNLn7YBSV1joe3HV</guid>
            <pubDate>Thu, 27 Oct 2022 14:33:19 GMT</pubDate>
            <description><![CDATA[Initial Attempts to Reverse Engineer Belisarius For an introduction to this series, see here. For quick reference, Belisarius is the nickname I rather arbitrarily gave to the address 0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf on Ethereum mainnet, which I’ll try to explain another time.ArtThis article’s art was created by Etheria Chan as a part of some explorations in generated images, and guided by a vision of the subject matter as a cyberpunk investigative journey. If you decide to mint this...]]></description>
            <content:encoded><![CDATA[<p><em>Initial Attempts to Reverse Engineer Belisarius</em></p><p><em>For an introduction to this series, see </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/wschwab.eth/CjODHmpDMTbZsAACyFJyFJkB3YakZqH8KUko4AOTMkA"><em>here</em></a><em>. For quick reference, Belisarius is the nickname I rather arbitrarily gave to the address 0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf on Ethereum mainnet, which I’ll try to explain another time.</em></p><h3 id="h-art" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Art</h3><p>This article’s art was created by <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/echanneled">Etheria Chan</a> as a part of some explorations in generated images, and guided by a vision of the subject matter as a cyberpunk investigative journey. If you decide to mint this article as an NFT, the revenue will be split 50/50 between Etheria and myself.</p><p>The image was cropped to fit Mirror’s format for cover art, if you’d like to see the full original, see <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://odqohi2sqxbz3fdkietivpttlkdl2ekc4xbiueaupcen3anpkfvq.arweave.net/cODjo1KFw52UakEmir5zWoa9EULlwooQFHiI3YGvUWs">here</a>. (Thanks to zkDoof again for the help uploading it.)</p><h2 id="h-preface" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Preface</h2><p>Belisarius is a contract. This decision is already interesting to me - I’m not sure what the advantage of using a contract over an EOA bot, but I’ve seen this in other bots too. My first thought was that this seemed disadvantageous since it would seem terrifically restrictive, since contracts should only be able to operate strategies coded into them, and it’s hard to believe they could be expressive and general enough to cover the gamut of strategies that could present themselves. As you will find here, that thought was indeed in vain.</p><p>Once upon a time I had a pair programming/learning session weekly with <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/th4s_">th4s</a>. We had worked on a better understanding of Yul-level assembly and opcodes, and were looking for a new project. A quick glance at the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/address/0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf#code">Contract section on Belisarius’s Etherscan page</a> will show that the code is (as one would suspect) unverified, so we decided we’d try and understand what this contract is and how it interacts with the chain. This was the first step in falling down the Belisarius rabbit hole.</p><p>As a warning, the telling here is roundabout. We could unceremoniously drop the conclusions here, but in my humble opinion, a lot of the value is in the journey. Perhaps I’m mistaken, but I feel that literature on attempting reverse engineering a contract is scant, and the process as it looked like to a plebeian engineer such as myself may be in and of itself useful. It’s certainly therapeutic for me.</p><h2 id="h-first-steps" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">First Steps</h2><p>th4s recommended <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethervm.io/">EtherVM</a> as a decompiler. You can see the decompilation for Belisarius <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethervm.io/decompile/0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf">here</a>. EtherVM gives a pretty good readout of the functions in the contract at the top, which we’ll get into. You may notice that a surprising number of functions are named for us at the top of the page. If function names aren’t stored in the contract code (they aren’t), how does EtherVM know what the names and arguments are? The answer is that the function selectors are stored in the contract (those are the first 4 bytes of the keccak256 hash of the function signature, and the function signature the name of the function and the argument data types packed, for example <code>“transfer(address,uint256)”</code>, see <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/linum-labs/a-technical-primer-on-using-encoded-function-calls-50e2b9939223">this</a> excellent article by Veronica Coutts for more). There is a popular database of function selectors and the function name/arg combo which produces it called <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.4byte.directory/">4byte.directory</a>, and EtherVM queries it with the function selectors it detects in contracts. (It might be interesting to dive into <em>how</em> EtherVM detects function selectors, since I have seen contracts where it couldn’t figure out where the selectors were, but I suspect that’ll be a topic for later, maybe when we start diving more into strategy contracts.) Truth is, a bunch of things use 4byte - it’s also how Etherscan identifies which functions are being called, along with MetaMask.</p><p>In any event, as mentioned, a bunch of the functions are actually named by 4byte, which is kind of fascinating for a contract which we would expect to be all shadowy-like. A bunch of the names don’t seem too descriptive though; “rely” and “deny” seem like opposites, but what are they doing? What are “wards”? We all know what a cache is, but what is it doing here? I found some answers in a surprising place, but as mentioned, we’re taking the high road here. In truth, there’s a big shortcut to finding out what’s going on over here, but I went the long way, and I figure it might be fun and/or instructive for people if I describe what that long way was, and it’s at least cathartic, so here we go.</p><h2 id="h-executeaddressbytes" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"><code>execute(address,bytes)</code></h2><p>Looking casually through Belisarius’s transactions, we can see that most of them are interactions with the <code>execute</code> function, or more precisely functions, since <code>execute</code> is an overloaded function on Belisarius - one takes <code>(address,bytes)</code>, the other <code>(bytes,bytes)</code>. (Though the vast majority of calls, or maybe even all of them, I don’t recall, are to the <code>(address,bytes)</code> variant.) I don’t remember the precise series of events, but I think we decided to try figuring this function out first.</p><p>Looking at the decompilation on EtherVM shouldn’t be that unfamiliar if you’ve looked through a contract in <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/FuelLabs/yulp">Yulp</a> or <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://huff.sh/">Huff</a>, but in case you haven’t, we’ll break it down a bit. I want to emphasize “a bit”, since there are a ton of lines here that I don’t particularly understand since at the end of the day I’m simply not all that gigabrained. I’ll just focus on what we did reason about, and somethings I’ve figured out later. The first point of interest is the if/else if flow that starts a few lines in. This is represented in Yulp and others as a switch table, and it’s for figuring out if a call to the contract is interacting with any of the contract’s functions or not. Any call made to a contract which is supposed to call a specific function starts with the function selector (which we explained above), so the switch table simply tries to match the first 4 bytes of the call with all of the function selectors in the contract. Those 4 bytes are represented as <code>var0</code> in EtherVM here.</p><p>Incidentally, you may be wondering why the if/else ifs are nested in another if which checks if <code>0x78e111f6 &gt; var0</code>. This is a search optimization. By ordering the functions in order of the hexadecimal of their selectors, even though that would seem irrelevant, calls to functions in the second half of the list (the ones with higher hex values) is reduced. This is a common optimization in many areas of coding, and is called a binary search.</p><p>The very first selector is the function we’re interested in - <code>execute(address,bytes)</code>. I seem to remember our original intuition is that this would be something like <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/makerdao/multicall">multicall</a>, allowing batching together a bunch of calls into one tx. Looking back, it should have been more suspicious that the first argument was <code>address</code> and not <code>address[]</code>. I’ll add some intuition I’ve gained from looking at EtherVM. Inside the jump table usually all that I’ve seen so far is slicing the selector from calldata, and then saving the length of the calldata minus the first four bytes (the selector), and then passing them along. There can also be checks to make sure the calldata is long enough to support its arguments. After that, the first jump is generally to datatype validation and processing (but not always). In particular, if there are arrays, this is where they’ll be unpacked. I plan on getting into that more in the sequel to this chapter, where we dive into a function with an unknown selector. After that, EtherVM places in another jump to an arbitrarily named internal function (which isn’t necessarily an internal function in the source code, as far as I can tell). In this case, after the initial check there’s a jump to something EtherVM calls <code>func_0603</code>.</p><p><code>func_0603</code> starts by loading <code>msg.sender</code> and a bunch of zeros into the first 64 (0x40) bytes of memory. If you’ve read up on mappings, you can tell the next line is checking a mapping using <code>msg.sender</code> as the key, and expecting it to return 1, reverting if it doesn’t. This is a basic auth check using a mapping as a whitelist of addresses that can call functions like this. I think understanding this was around when I felt like a 1337 Hackerman.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://tenor.com/view/hacker-hackerman-kung-fury-gif-7953536">https://tenor.com/view/hacker-hackerman-kung-fury-gif-7953536</a></p><p>Of course then Belisarius made me cry by throwing a <code>delegatecall</code> at me. Those have a bunch of arguments, and the memory slicing in the decompiler made my eyes water. It took us a while to realize what was going on here. We found it a bit easier to use Etherscan to figure out what was happening. Looking at some txs there combined with the decompilation, we eventually reasoned that Belisarius deploys “strategy” contracts, and then calls into them using <code>execute</code>; the strategy contract is the address being supplied as an argument. <code>execute</code> then <code>delegatecall</code>s the strategy contract, and executes using the bytes data as the call it’s supposed to make to the contract (at least as far as we can tell).</p><p>If you aren’t familiar with <code>delegatecall</code>, there are excellent resources out there, but it shouldn’t be too hard to explain it here if you’ve made it this far. <code>delegatecall</code> allows Belisarius to call the strategy contract and execute code there as if the code was in Belisarius all along. That’s why if you look at an<code>execute</code> tx from Belisarius on Etherscan (in regular view) you won’t see it calling another contract to execute the strategy. If you do want to see it, click on a transaction, then click on internal txs, and switch to advanced view. You should be able to see the <code>delegatecall</code>s to the strategy contract now.</p><p>I got a headache trying to figure it out then, but looking at it now, I’m pretty sure that if you follow it all through, the second argument passed to <code>func_0603</code> is simply the length of the data for the call, and that it slices from after the address argument to the end of the data, and <code>delegatecall</code>s with that to the address. The <code>temp1</code> variable is something you’ve probably noticed in Solidity calls - <code>call</code> and <code>delegatecall</code> return a boolean indicating if the call was successful or not. That’s the reason it’s checked right after the <code>delegatecall</code>, and if it isn’t <code>0x01</code> - <code>true</code> - that the whole thing reverts.</p><h2 id="h-wardsaddress" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"><code>wards(address)</code></h2><p>Understanding the first execute function helped us understand another function. <code>wards</code> is the last function in the <code>if</code>s (jump table). The first check there reverts if there is <code>msg.value</code> - we can understand that means that it is not a payable function. (Conversely, <code>execute(address,bytes)</code> did not have this check, meaning that it is payable. I don’t see anywhere in the code of the function that deals with value, leaving me to suspect it was made payable as a gas optimization since doing so avoids needing to check if there is any <code>msg.value</code>.) Much like we saw at the beginning of the execute function (before jumping to an internal function) it first does some data validation, then hops to an internal function where it checks a mapping using the address supplied as the argument as the key, and returns the value. Easy peasy.</p><p>Explained in other words, this is a view function returning a value from the mapping being used as auth - you can check if an address is whitelisted to call functions like execute using this function. In fact, the mapping itself likely has public visibility, and this would be the getter function generated by Solidity for it.</p><h2 id="h-rely-and-deny" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"><code>rely</code> &amp; <code>deny</code></h2><p><code>rely(address)</code> and <code>deny(address)</code> were the next ones we figured out. Knowing that there is an access list implies a way to get addresses on (and maybe off) the list, and since both <code>rely</code> and <code>deny</code> have address as their lone argument, it stood to reason that it was them. Long story short, it is, you can follow the code yourself, it should be pretty straightforward after the above.</p><h2 id="h-executebytesbytes-and-a-big-spoiler-of-the-best-kind" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"><code>execute(bytes,bytes)</code> and a big spoiler of the best kind</h2><p>I was still really curious about the second <code>execute</code>. We had some ideas about what it might be. One of the things that was nagging at me was trying to figure out if there was anything in the contract about deploying strategies, I thought that might happen here. The decompilation was too hard for us to parse, though. I had another thought from looking at all the loops that seemed to be happening was that maybe it was some kind of custom tx bundling like <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/weiroll/weiroll">weiroll</a>. We were stumped.</p><p>This is where it’s time to reveal a big ‘ol spoiler though. Some time later, I was looking through Maker’s code with a colleague (nothing connected, just independently <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://youtu.be/mH2WCbu7zss?list=PLtQA_IktTCnZcITKc6Bj2Y8jtf33n5ZDk&amp;t=412">looking</a> through the repo) when I was confronted by the following code:</p><pre data-type="codeBlock" text="mapping(address =&gt; uint) public wards;
function rely(address usr) external auth { require(live == 1, “Vat/not-live”); wards[usr] = 1; }
function deny(address usr) external auth { require(live == 1, “Vat/not-live”); wards[usr] = 0; }
"><code><span class="hljs-keyword">mapping</span>(<span class="hljs-keyword">address</span> <span class="hljs-operator">=</span><span class="hljs-operator">></span> <span class="hljs-keyword">uint</span>) <span class="hljs-keyword">public</span> wards;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rely</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> usr</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title">auth</span> </span>{ <span class="hljs-built_in">require</span>(live <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">1</span>, “Vat<span class="hljs-operator">/</span>not<span class="hljs-operator">-</span>live”); wards[usr] <span class="hljs-operator">=</span> <span class="hljs-number">1</span>; }
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">deny</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> usr</span>) <span class="hljs-title"><span class="hljs-keyword">external</span></span> <span class="hljs-title">auth</span> </span>{ <span class="hljs-built_in">require</span>(live <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-number">1</span>, “Vat<span class="hljs-operator">/</span>not<span class="hljs-operator">-</span>live”); wards[usr] <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; }
</code></pre><p>While this isn’t the exact same code as Belisarius (for example, Belisarius reverts without any error message), there’s no mistaking that it’s the same functions as Belisarius.</p><p>MakerDAO’s contracts were written by DappHub, a group of absolute Solidity chads. The ds you see all over the place in the contracts stands for DappSys, which is what they called their contracts, if I’m not mistaken. If I was more intelligent I would’ve looked to see if I could find <code>execute(bytes,bytes)</code> somewhere in Maker or DappSys code. I wasn’t that intelligent, and only much later thought of searching .sol files in Github’s advanced search for <code>execute(bytes,bytes</code> to see if I could find something calling it, which of course ended up sending me to DappSys’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/dapphub/ds-proxy/blob/master/src/proxy.sol#L38-L51">ds-proxy</a>:</p><pre data-type="codeBlock" text="// use the proxy to execute calldata _data on contract _code
function execute(bytes memory _code, bytes memory _data)
    public
    payable
    returns (address target, bytes memory response)
{
    target = cache.read(_code);
    if (target == address(0)) {
        // deploy contract &amp; store its address in cache
        target = cache.write(_code);
    }

    response = execute(target, _data);
}
"><code><span class="hljs-comment">// use the proxy to execute calldata _data on contract _code</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">execute</span>(<span class="hljs-params"><span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> _code, <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> _data</span>)
    <span class="hljs-title"><span class="hljs-keyword">public</span></span>
    <span class="hljs-title"><span class="hljs-keyword">payable</span></span>
    <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">address</span> target, <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> response</span>)
</span>{
    target <span class="hljs-operator">=</span> cache.read(_code);
    <span class="hljs-keyword">if</span> (target <span class="hljs-operator">=</span><span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(<span class="hljs-number">0</span>)) {
        <span class="hljs-comment">// deploy contract &#x26; store its address in cache</span>
        target <span class="hljs-operator">=</span> cache.write(_code);
    }

    response <span class="hljs-operator">=</span> execute(target, _data);
}
</code></pre><p>Apparently the original guess had been in the right direction; this <code>execute</code> function took contract code and calls to make to the contract as arguments, deployed the contract code and then called it with the second argument as a payload.</p><p>You can also find the <code>cache</code> and <code>setCache</code> functions in ds-proxy, by the way.</p><p>All of this points to Belisarius being a DappSys contract, or at least a contract built with DappSys building blocks. To be very clear, I don’t think this even remotely implicates DappHub as being the operators of Belisarius, the same way that they aren’t MakerDAO.</p><h2 id="h-the-unknown-functions" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The Unknown Functions</h2><p>The discoveries with DappSys struck me as potentially useful for another puzzle in Belisarius. As mentioned above, most of the Belisarius’s functions are recognized by 4bytes. There are two that are not: <code>0x78111f6</code> and <code>0xa90e8731</code>. Perhaps the other DappSys contracts would be a good place to look for a match, though I don’t know an easy way to do this. (A <em>not</em> easy way would be using something like Foundry’s cast, and doing <code>cast sig</code> on anything promising. Naturally, I&apos;ve tried this out.)</p><p>I suspected originally that this wouldn’t be too hard a task, but has been quite a task, and I’ll defer it to its own chapter.</p><h2 id="h-other-loose-ends" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Other Loose Ends</h2><p>There are a couple of interesting things I noticed as I was cleaning up a gist attempting to loosely reconstruct Belisarius (linked later) in order to share it. One is yet another DS reference. If you look through the decompilation for the <code>setCache</code> function, there is a revert there which actually has an error message - most don’t. In the decompilation a couple of lines before, you can see a big hex string get put in memory. Without bothering to check, I suspected that this was the error string.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/ebc55e56e0b1b929593b0f5113b58490547ab2c4963bb9631d36014a663716a9.png" alt="raw error hex" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">raw error hex</figcaption></figure><p>Looking at ds-proxy, <code>setCache</code> does indeed have an error string:</p><pre data-type="codeBlock" text="“ds-proxy-cache-address-required”
"><code>“ds<span class="hljs-operator">-</span>proxy<span class="hljs-operator">-</span>cache<span class="hljs-operator">-</span><span class="hljs-keyword">address</span><span class="hljs-operator">-</span>required”
</code></pre><p>I suspected the big hex was the encoding for the error string, and was curious if it would match up. Try it yourself - the hex string is <code>0x64732d70726f78792d63616368652d616464726573732d726571756972656400</code>, and you can search online for a hex to text decoder.</p><p>Another point of note was around events. In Etherscan there’s an events tab which displays the events emitted by a contract ordered by most recent first. Glancing at Belisarius’s tab we can see that Belisarius does indeed emit events. <code>topic0</code> is always the same, which implies that we’re always dealing with the same event. (If you’d like to learn more about events and what <code>topic0</code> is, I have an <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/linum-labs/everything-you-ever-wanted-to-know-about-events-and-logs-on-ethereum-fec84ea7d0a5">old blog post</a> that I wrote for my previous employer, Linum Labs, which I’m personally fond of.)</p><p>A control-f search of the decompilation doesn’t turn up any events in the decompiled code (search for <code>log</code>, which is what the decompiler uses to signify an event being emitted). If you did search, though, you’ll see one does come up in the disassembly. It seems strange for the event to show up in the disassembly without being in the decompilation, and truth be told, it kind of looks like unreachable code in the disassembly. There’s another inconsistency that I caught on to, and there might be even more. Long story short, if you look ahead to the Compiler Version section, you’ll see that this is a red herring, though. This does present a conundrum, albeit one with a potentially simple solution. If Belisarius has no events in the contract, how come Belisarius emits events? A simple answer after decompiling the <code>execute</code>s would be that the events are actually in the strategy contracts, but emitted from Belisarius since Belisarius is <code>delegatecall</code>ing in. I don’t know if this is correct, but it’s certainly my current hypothesis.</p><p>Looking at ds-proxy (since at least by now I realized I should always be looking at ds contracts to try to place things), you’ll see the note modifier used on <code>execute(bytes,bytes)</code> and <code>setCache</code>. <code>note</code> is imported from the lib folder in ds-proxy (for those of you unfamiliar with DappTools or Foundry, that’s where imported libraries are in those frameworks), and if you follow it through, you’ll find that the <code>note</code> modifier wraps a function, initializing some variables at the beginning, and emitting an event (<code>LogNote</code>) using them and some globals at the end. Saying the event is <code>LogNote</code> doesn’t totally check out, though. If you look at ds-note, the note event is anonymous with four indexed arguments. This should generate 4 topics. Belisarius, however, uses <code>LOG1</code>, which means only one topic is being emitted. Also, we can see that the event is also emitted when <code>execute(address,bytes)</code> is called, not just <code>execute(bytes,bytes)</code>, but at first glance not every time that <code>execute</code> is called, which implies that the operators have a way to elect to emit the function or not. This implies a few mysteries which I’ll need to save for later (or never).</p><p>Going back to the actual event, if you put <code>topic0</code> into <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/samczsun">samczsun</a>’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://sig.eth.samczsun.com/">signature database</a> (which allows you to search entire signatures and also text-to-selector/signature, unlike 4bytes, which is only selector-to-text) we can actually determine exactly what the event is:</p><pre data-type="codeBlock" text="log_named_uint(bytes32,uint256)
"><code><span class="hljs-built_in">log_named_uint</span>(bytes32,uint256)
</code></pre><p>I had a suspicion this would be in DappSys’s ds-test, which it <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/dapphub/ds-test/blob/master/src/test.sol#L34">is</a>. One noteworthy difference is that the current ds-test has a slightly different signature, using <code>string</code> for the first argument instead of <code>bytes32</code> like Belisarius does. If you look at the version of ds-test from back when Belisarius was deployed, though (<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/dapphub/ds-test/blob/a4e40050b809705b15867939f5829540c50cb84f/src/test.sol#L25">here</a>), you’ll see ds-test was indeed using <code>bytes32</code> as the first argument then.</p><p><code>bytes32</code> is often a cheaper way to work with strings than string, and DappSys in particular seemed to embrace that, from what I remember. (One of their devs told me once about something completely different that it’s always better to use a fixed-size datatype than a dynamic one, another possible reason for the preference.) Playing around with Belisarius’s events on Etherscan, it does indeed seem that the first field in the event is being used for text, all of the ones I looked at said “availableAmount”, which in turn makes it stand to reason that the second argument represents some value in wei or something like that. If I wasn’t lazy I’d match it up against the <code>msg.value</code> and/or remaining value to Belisarius after the transaction. I am lazy, though. Back when I thought that this was an event on Belisarius itself, I took some placeholder shots in the dark on the gist, which at this point I don’t even think could be right. Basically I put that the <code>bytes32</code> is parsed from calldata in the same place where <code>LogNote</code>’s bar argument was. I put <code>msg.value</code> as the second arg since I’m lazy and it’s easier than trying to code something to figure out how much value is left after the <code>delegatecall</code>. I also put the <code>note</code> modifier on both <code>execute</code>s (unlike ds-proxy), and removed it from <code>setCache</code> since I have a suspicion that it’s only for the value-moving txs. (I also modified the <code>note</code> modifier to fire the <code>log_named_uint</code> event instead of <code>LogNote</code>.) As stated before, it doesn’t seem to fire on every <code>execute</code>, so there’s obviously a lot missing here, but I don’t know what the guidelines are, so I left that out too.</p><p>The last thing I’d like to point to in this section are return values. In the gist where I take a shot at reconstructing Belisarius I keep the return values from the ds-proxy functions they’re based on and maybe copied from, but I am not too sure from the compilation that Belisarius’s implementation actually returns anything.</p><h2 id="h-compiler-version" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Compiler Version</h2><p>Another interesting detail, though perhaps of no import in unraveling Belisarius’s components, is what compiler version was used. Someone who’s way better than me at this told me that the Solidity used for the contract is pre-Constantinople. The Constantinople hardfork happened at 7,280,000 so it was technically live when Belisarius was deployed, but the compiler used to compile the bytecode does not use opcodes included in Constantinople, meaning the version of the compiler being used hadn’t implemented them yet. The opcodes pointed out to me were native bitshift opcodes like SHR (from EIP-145).</p><p>Looking through Belisarius’s disassembly, though, you can see that there is actually on SHL (left bitshift) towards the very end, right around where the only <code>LOG</code> opcode is. This is very strange, since if the Constantinople opcodes were available, the optimizer should have prioritized them over division for bit operations, which is not the case (as mentioned above). Someone who saw an earlier version of this shed some light on both the SHL and the LOG. Solidity has a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.soliditylang.org/en/latest/metadata.html">spec</a> for contract metadata, which is encoded at the end of the contract. At least in this contract, it would seem the last 43 bytes are reserved for the Swarm hash of the metadata. This means that both the <code>SHL</code> and <code>LOG1</code>, despite being the right hex codes for those opcodes, are actually just part of a non-EVM encoding, and can be totally ignored.</p><p>This was part of a larger conversation about the compiler version, itself. The same person who tipped me off to the metadata has resources about deducing the Solidity version of a contract by analyzing the initial bytecode. Most Solidity starts with 60806040 (which is how it initialized the free memory pointer), but the continuation of the string often helps narrow down to a more specific subset of versions. From Belisarius’s opening <code>608060405260043610</code>, he was able to narrow it down to 0.4.22 through 0.5.1. Once the field was that small, I did some more digging by sifting through the changelogs for those versions of Solidity to see if there was something that would help me narrow it down even further. As it happens, as far as I can tell <code>staticcall</code> was only introduced in 0.5.0, and is used by Belisarius, which should mean that Belisarius was compiled with either 0.5.0 or 0.5.1.</p><p>Also, as far as I can tell there should be some way to extract the version from the Swarm hash, but I do not know how. I assume this is from when Swarm was a bit of a network than it is now, and any Swarm gateway I’ve tried with the metadata hash come up empty, which leads me to believe that the data is no longer on their network. There still might be someone who maintains a mapping of particular hashes to versions, if anyone knows anything about this, please let me know.</p><h2 id="h-the-gist-of-things" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The Gist of Things</h2><p>I’ve been keeping a bit of a reconstruction of Belisarius in a gist. It isn’t meant to produce the same exact bytecode as Belisarius, and indeed won’t even compile as of this writing since I just use the selector to name the functions I don’t know the name of. You can find it <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://gist.github.com/wschwab/e5794a8c3a25a98dcd8dfd54a69c4baa">here</a>.</p><p>Just to be very clear, much of what is there is guesswork. Like I mentioned before, it isn’t meant to be a 100% recreation, more of an idea of what’s going on in Belisarius.</p><p>(Though it has spoilers for <code>0x78e111f6</code>, so don’t ruin the fun for yourself before you read the next chapter.)</p><h2 id="h-conclusion" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Conclusion</h2><p>This should give some initial insight into Belisarius. Truth is, this doesn’t really have any bearing on understanding the actual txs Belisarius performs, most likely, though for me this isn’t really about cutting straight to the competitive part. It’s fun for me to just noodle around the bytecode and see what we can get out of it. If it’s also fun for you, maybe we can find a support group and go together.</p><p>There’s so much more to do here! There are still two functions we haven’t cracked, I plan on dedicating the next chapter to getting what we can figure out about them written down. That’s all before we start really analyzing the ops, who’s calling Belisarius, what they’re doing, how they’re doing it, and whatever else we can learn by checking the chain.</p><p>I’m hoping this was interesting, useful, and/or informative for you, anon. Like I mentioned before, much of this is built on foundations much larger than myself, and making frens along the way has been very enriching. If you’d like to collaborate, feel free to reach out.</p>]]></content:encoded>
            <author>wschwab@newsletter.paragraph.com (Will Schwab)</author>
            <enclosure url="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/50940dd6b599aab0370ee54e7ef06235237b076241d4c013b6e6c41a80fd1abb.png" length="0" type="image/png"/>
        </item>
        <item>
            <title><![CDATA[Loot, Rarity, and Beyond]]></title>
            <link>https://paragraph.com/@wschwab/loot-rarity-and-beyond</link>
            <guid>jNU51eGiZhyD6IfildcZ</guid>
            <pubDate>Wed, 31 Aug 2022 16:49:36 GMT</pubDate>
            <description><![CDATA[Thinking about the confluence of games and blockchainLootOne of the runaway success projects of 2021 was Loot. While hard to summarize the entire phenomenon briefly, the actual technicals of the project are indeed very concise: NFTs with on-chain metadata formed as an SVG image with a list of fantasy-themed gear. (You can check it out on OpenSea here.) The reason why it took off, at least in my humble opinion, was the promise that it carried with it. It was an interesting primitive - fully on...]]></description>
            <content:encoded><![CDATA[<p><em>Thinking about the confluence of games and blockchain</em></p><h2 id="h-loot" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Loot</h2><p>One of the runaway success projects of 2021 was Loot. While hard to summarize the entire phenomenon briefly, the actual technicals of the project are indeed very concise: NFTs with on-chain metadata formed as an SVG image with a list of fantasy-themed gear. (You can check it out on OpenSea <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://opensea.io/collection/lootproject">here</a>.)</p><p>The reason why it took off, at least in my humble opinion, was the promise that it carried with it. It was an interesting primitive - fully on-chain metadata - and the items were designed with the mystique that hinted at an interesting story. I find it reminiscent of finding a really hype piece of character art, trying to figure out what series it’s from only to find out that it’s actually just a standalone piece. A community formed around it, and it seems clear a whole lore will form around them too. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://domhofmann.com/">dhof</a> managed to frame the creative seed of an idea, and hand it off to the community to nurture and grow.</p><p>While there have been a number of projects that have spun up around Loot (such as Lootloose, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://lootcharacter.com">lootcharacter</a>, AGLD, Realms), I personally have not seen a convincing game spring up around it. (The bottom of the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://lootproject.com">Loot site</a> says Quests are “Coming soon”.) This isn’t a criticism of Loot, but a subject I’d like to dive into a bit.</p><h2 id="h-rarity" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Rarity</h2><p>Shortly after Loot, Andre Cronje developed <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://andrecronje.medium.com/loot-rarity-d341faa4485c">Rarity</a>. Rarity launched with a bit more framework than the absolute minimalism of Loot. There were characters (which could have their base stats rendered as on-chain SVGs a la Loot), and a basic stat framework which could and has been extended reminiscent of the D&amp;D d20 system. Like Loot, an impressive community of builders has sprung up around the project, and have extended into skins and even adventures which allow “summoned” characters to accrue experience points (and by way of that levels) and items. For those interested in taking a look, Facu from Yearn maintains a frontend which aggregates much of the community building around the project called <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://rarityextended.com/">Rarity Extended</a>.</p><p>While Rarity does have some game elements, I would personally call it barely a game at this point. Characters can level up by grinding a daily adventure, but there is no skill or variance involved in it. To be honest, the most convenient way to play would be to simply write a bot that could monitor when a character can adventure and send the daily txs. Again, this is not a criticism - Andre certainly never claimed that it was anything other than what it is.</p><p>I do believe there are teams in both ecosystems working on creating fuller games around both projects (and even some work on integrating the two with each other despite having been deployed on different chains - Loot is on Ethereum’s mainnet, and Rarity is on Fantom’s Opera mainnet).</p><h2 id="h-on-chain-games" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">On-chain Games</h2><p>Looking at these two projects, and also dabbling a bit in other games such as Neon District, has led my thinking down a few different paths. One is that there is clearly a feeling that blockchain has something to give to RPG-style games. It is hard for me to imagine Loot and Rarity both striking the chord they did without that. That’s an arguable point, but the underlies the rest of my thoughts here. The others are an exploration of what that connection might be.</p><p>Just a warning: I might talk like I know what I’m talking about here. It’s just the way I think about things. Game dev is a field I do not know a large amount about, and some of the things I think I know about it may be flat out wrong. If you find something like that here, please do hit me up on Twitter and let me know.</p><p>One of the first thoughts I’ve had is around how hard it is to come up with something that can be made on chain for Rarity. Part of this is an issue with randomness on-chain, at least from where I see it. Randomness is often used in games, both tabletop (dice) and the computer kind. The current state of blockchain can be hard to get randomness out of, and even when there is limited randomness, there is generally a way to game the randomness, meaning that there inherently becomes a side-game of being able to game the engine.</p><p>(Computer games traditionally also use weak randomness, but are less transparent and permissionless that a blockchain. Blockchain gives a unique level of access to the game engine if the engine were to be on-chain.)</p><p>There’s nothing wrong with a side-game like that. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://zkga.me">Dark Forest</a> has really embraced bots, and is turning into a game that can be played for fun manually, but is rapidly becoming a bot-creating game at higher levels. (There’s also a side-game of creating alliance DAOs there.) I saw to day that Max Wolff posted <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/maxcwolff/status/1480350425446559758">a really fascinating thread</a> about the future of games like this. It’s still not what I’d like to focus on here - I’m more interested in exploring the intersection of narrative-motivated games and blockchain.</p><p>I think this is actually where a lot of the issues come up. The blockchain doesn’t have space or capacity for the breadth of a good narrative-driven RPG. For the computer versions of RPGs one of the issues would be decision trees - games with multiple endings or various relationships would need to somehow place these trees on-chain, where they would also be transparent, at least in a world where the whole engine would be on-chain. (Though I wonder if there’s something that can be done with either merkle trees or zero-knowledge proofs.) Another would be the actual dialogue and interaction - strings are expensive, and even if everything is represented as an IPFS link, it runs into all dialogue being freely viewable even without playing by virtue of being on a public, transparent network. Aside from that, there is the consistent issue of constant transactions to do anything. Imagining each move and attack as separate transactions, waiting for each to get mined, paying for tx fees on everything, is really unspeakable. Neon District gets around this by having an in-app wallet that auto-sends txs in the background, but I feel like that is a solution specific to more closed games, whereas I’m trying to focus on more open-ended projects.</p><p>When comparing to tabletop games such as D&amp;D, the divide seems to great to bear imho. Not only are systems like the full d20 system from Wizards of the Coast terrifically complex (meaning large amounts of code on-chain), and also copyrighted, but in addition, at least in my opinion the real allure of tabletop is that the possibilities are quite endless. Whereas anyone who ever played an RPG has experienced the frustration of knowing the bartender has the item you need, or that the door you need to go through is right behind him, you can’t figure out how to get him to give it to you or move out of the way. Many have spent countless hours screaming at the screen and smashing their controllers into the furniture just wishing they could ask someone what the bartender means when they say “only if you bring the tooth will I move”. (Not me, though. I’ve just heard about this from others. Of course.) Tabletop solves this by not needing code for every kind of interaction. The game is limited by the creativity of the players and adaptability of the game runner. (Those can be large constraints, and both take a lot of skill to be done well, but that’s also true of those making and playing computer games.) If anything, at first glance blockchain offers only the worst of both worlds - an inadequate, clunky system that would mean narrowly defining possible actions without giving the immersive experience moving to the screen is supposed to offer.</p><p>So where could these two ideas meet?</p><h2 id="h-a-proposal" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">A Proposal</h2><p>I’d like to propose a different direction for blockchain RPGs, one that tries to enhance the tabletop medium as opposed to replace it with on-chain mechanics. I think that blockchain has some attractive things to offer for this paradigm, and I’ll try to list them.</p><p>First, let’s start with a challenge and limitation the tabletop world has faced when compared with MMORPGs: people enjoy being able to exist in the same world and interact with each other. Being part of a story together bonds people, even if it’s just watching an event in Fortnite at the same time. While many TTRPGs have settings and storylines, it is difficult to call this really playing in the same world. Even if I’m in a game set in Forgotten Realms and you’re in a different game in Forgotten Realms, it isn’t so much of a shared world. The different game runners may portray events and characters differently, make different global events happen, and more likely than not, will not make the actions of the other group ‘canon’ in their version of Forgotten Realms. In blockchain terms, it’s more like they each forked their own instance of Forgotten Realms than that they’re both playing in Forgotten Realms together. In other words, they can’t create a setting that is ultimately larger than the room it is played in.</p><p>There have been groups that try to transcend this. The <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dnd.wizards.com/ddal_general">D&amp;D Adventurer’s League</a> has a system which allows you to have a character you can play in any DDAL chapter, and can level up a character traditionally. I am not personally familiar with the group, but have my suspicions as to the limitations of the League. I doubt groups are, by default, aware of each other in-game, and I also doubt that these sessions can affect the overall Forgotten Realms storyline (“metaplot”). I am only somewhat aware of the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.modernenigmasociety.org/">Modern Enigma Society</a>, though I suspect they have more of a chance at being able to do something like we’re describing here, especially since to the best of my knowledge there is no active metaplot in their setting, allowing them to easily be able to dictate their own metaplot.</p><p>While there would still be a high coordination cost, I believe there is space for blockchain to help with settings like these. While I debate if it can be useful as a mechanism for coordinating metaplot (perhaps by having a contract that stores pointers to IPFS write ups), it seems easy enough for it to serve as a database of characters (PC and NPC) and their stats. Approved game runners and maintainers will have access to updating stats on chain. This allows the character progression to be handled traditionally, and once finalized to be brought on chain. Rudimentary details like location could be useful in building a system that makes it easy to coordinate and understand which characters are in a region.</p><p>There would still be a great deal of effort needed to make a system such as this work. In addition, there are limitation to how much it <em>could</em> work. No one is going to take the time to commit every barkeep and weaponsmith to the chain. This obviously makes for a certain level of discontinuity between specific games. I think it’s still enough of a contribution as to be meaningful.</p><p>Another development in the TTRPG space that I find very relevant is the rise of remote sessions of RPGs held over services like Zoom. Whereas games used to be played around one table (hence the name), a number of advancements and a global pandemic locking us all up has moved the space of remote games greatly. One particular advancement that should be spotlighted is the virtual tabletop (VTT). These excel at bringing a battle maps (grids of areas, generally needed for combat) to life, allowing anyone connected to a server to easily see what their character is able to see, and often providing easy access to a number of in-game abilities (for example, seeing where your wizard would be able to cast <em>Fireball</em> and who it would affect). <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://foundryvtt.com/">Foundry VTT</a> (not to be confused with the smart contract framework), in general, has excellent ethos, including actively promoting user-created integrations. We could imagine a system that could read characters in from the chain, and also optionally write important information to it.</p><p>One of the reasons something like Foundry can be important is for allowing games to have a greater scope than their irl setting. If you know there is a super powerful mage (player character) who it makes sense for your group to talk with and ally with, the ability to coordinate them into the same game is necessary, even if the human playing the character is half a world away. As always, blockchains are good at creating an open ledger to coordinate around, and I could imagine it being a part of facilitating worlds such as these.</p><p>Something else worth mentioning about the VTT phenomenon is that it should allow for more complex systems. Things like the d20 system draw criticism for being overly complex, but systems built to leverage things like VTTs can work on placing the complexity in places where it is primarily abstracted away from the end user (players). Algorithms for accuracy and damage in ranged attacks that decay over distance, for example, could be fairly complex and handled by the VTT engine automatically.</p><h2 id="h-architecture" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Architecture</h2><p>Talking about architecture might be helpful. I don’t mean to say this is the only possible architecture, but I think it helps illustrate the ideas here well. There are some assumptions made regarding the RPG system (for example, that there are experience points), but we’ve tried to be as minimal as possible.</p><h3 id="h-contracts" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Contracts</h3><p><strong>Characters:</strong> this could be something like Rarity’s ERC721 contract for players. Rarity bears similarities to the d20 system, which in its case means that there are also contracts for Skills and Feats. If necessary, a similar structure can be used here wherein there is one main NFT representing the character, and auxiliary contracts containing the other statistics. Coming up with a separate sub-architecture for characters may itself be a large part of structuring a project like this, though I suspect that as is generally the case with smart contracts, the more you could get onto one contract (or even into to one updating function) the better. This may push towards a game system that lends itself towards that.</p><p>In a system where characters can augment their base statistics through items, this may need to be reflected in the Characters contract, or alternatively through a special function with privileges in the Items contract. In the case of something like augmentations in a sci-fi setting, this may need a fair amount of thought, as the item providing the buff to stats may become destroyed or impaired. The easier solution would be having a function restricted to game runners that allows manipulating these stats, but an adequate solution not relying on manual input from game runners should be able to be implemented.</p><p><strong>Items:</strong> Loot provides ample inspiration for an items contract. Loot itself is unique packs of items, which then lends itself well to ERC721. On the other hand, an actual game should imply the ability to separate and use items out of the pack and equip them. Also, individual items are not unique. In the Loot ecosystem itself this led to the creation of Lootloose, which can break the “packs” of Loot into individual items in an ERC1155 contract. If anything, an ERC1155 contract of individual items is likely more necessary.</p><p>Properties (like houses) might exist as a separate ERC721 contract.</p><p><strong>Campaigns:</strong> Addresses whitelisted as game runners can initialize a Campaign in this contract. This might also be an ERC721 contract. A campaign should be able to accept characters, and perhaps also contain other details such as location. Campaigns should contain a function allowing a game runner to add Encounters. Successfully completed Encounters should give experience. This may necessitate a separate contract for antagonists or challenges. (Even though specific characters might be unique, an ERC1155 contract would likely work best for this.)</p><p>Using something like Auryn Macmillan’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-3722">Poster</a> could give a lightweight method to index story details on-chain without having to store them(merely emitting them as events).</p><p>XP could be awarded on the completion of an encounter, and also at a Campaign’s close. This relies on game masters to run legitimate games and not just let players gain experience without doing anything. This would also be true in any distributed tabletop game, though.</p><p><strong>DAO:</strong> Being that there is an entire system with a number of complex parameters, in addition to game masters possessing special permissions, it would make sense for there to be a central authority, which for some strange reason is usually called a DAO in this space. The DAO should have the ability to vote to remove and add game runners and take other actions to upgrade, tweak, and maintain the ecosystem.</p><p>An important note would be organizing this ecosystem so that it is narrative-first. This means eliminating certain vectors of pay-to-win. While I see no issue allowing someone to sell a character, allowing a different irl person to now control them, things attached to the character should happen organically in the story. This means that you shouldn’t be able to simply yield farm then buy Excalibur for your level-1 freshly minted summoner because you can afford it. Andre talks about this a bit in the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://andrecronje.medium.com/rarity-gold-with-a-twist-715f77051261">blog post</a> where he talks about the in-game gold in Rarity.</p><h3 id="h-foundry-vtt" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Foundry VTT</h3><p>I have very limited exposure to Foundry, so this section might be more mistaken than not. That being said, here are the items I’d anticipate Foundry, or something like it, could be used for:</p><ul><li><p>That being said, the ability to create maps both on a more macro level (world, continent, area, city) and more micro (specific house/installation, generally anything that needs a grid on it) as shared assets across all participants in the world. Permissioned parties should be able to list these assets as canonical by storing them on IPFS or similar and linking them either through Poster or a registry contract (or both).</p></li><li><p>A plugin that allows importing a Campaign and the characters participating from the Campaign contract, and a plugin that lets a certified game runner update the characters and Campaign through Foundry.</p></li><li><p>It would be amazing if there would be a plugin that could tell game runners relevant “news” about the locale the Campaign is in - who’s come to town, noteworthy events that have transpired either by other players or narrative developed about the setting (more on that in a minute).</p></li></ul><h3 id="h-additional-elements-and-challenges" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Additional Elements and Challenges</h3><p>This is just a general observation, but something like a Fandom wiki is most likely vital for organizing information about the setting, though I wish there was a more open platform that is as streamlined as they are. While Mirror is excellent, I don’t see it being able to handle a wiki-type format as neatly (yet).</p><p>An additional point and challenge to a large setting like this involves the development of the setting’s metaplot and the passage of time in general. It is unreasonable for 1 day irl to equal 1 day in game since people can’t game 24/7 (yet). This leads to some issues monitoring time. Let’s say there’s a game that meets once weekly, but another that meets monthly. Alternatively, a game that moves very slowly (perhaps bogged down by combat, character infighting, or even worse, player infighting) versus a game that moves more quickly (downtime while accomplishing a menial task such as building a shield commonly makes this happen). Games will not be in sync with each other. More than that, the general metaplot might not be in sync either, and the possibility also exists for details being retroactively added or changed. I don’t think there’s a simple answer to this, but I do think that it’s something that should be considered and worked with.</p><p>On that note, attention to the metaplot in general is a massive task. Looking at sprawling worlds like League of Legends or the MCU makes me wonder if they have people literally dedicated to keeping track of all the lore and making sure it more or less works. I don’t think they do, but they probably should. A job outside of the DAO, game runners, and players may be metaplot development. This itself might be two jobs - content creators, and overall lore “masters” who keep track of everything and work on preserving continuity. This brings me to what I think might actually be the last section in an article that is already an awful lot longer than I thought it would be.</p><h2 id="h-monetization" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Monetization</h2><p>If a system like this is going to work, it will most likely need to be monetized, imho. Monetization allows for paid maintenance to the system. This includes the devs responsible for the contracts and plugins, the DAO members, the writers, and lore experts. Optimally I think it should also include game runners. Running a game well is a time-consuming task, and game runners I know can prepare for hours per session. Treating it as a job rewards those skilled at it for their labour, attracts talent, and makes it more sustainable for them to invest in it. The question is where the funds should come from. I don’t have a single answer, but some ideas:</p><ul><li><p>I do not think that players should be obligated to pay per campaign, but I do think tipping the game runner should be made an easy part of the system, and encouraged.</p></li><li><p>Free-to-play often monetizes things like skins. An easy parallel here could be “seasons” of NFTs. If these NFTs can be partnered with other game oriented NFT sets in the space, perhaps as an airdrop target, that would increase their desirability. Imagine if Parallel would airdrop some of their new cards to NFT holders, for example.</p></li><li><p>Just to be clear, there is not a lot of room here for a valueless governance token, since there should be an expectation that the DAO is run by people who understand and actually care about the system. I suppose the system can literally release a valueless token with absolutely no utility and/or governance rights, and knowing this space, if it has hype it’ll probably work (that is pretty much what AGLD is), but I can’t say it feels right to recommend that.</p></li><li><p>A possibility that can be briefly detailed here is the possibility of additional games being set in the same world that are more clearly monetized. For example, if there is a separate 2D fighter game that leverages characters/settings from the world (but isn’t canon story), that games monetization (skins, price, defi integrations) can also help fund this ecosystem.</p></li></ul><h2 id="h-conclusion" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Conclusion</h2><p>This has been a pretty long journey looking at the space, and detailing a proposal for one direction it could move forward. I’m very interested in seeing where this space moves, and the frontiers it moves to explore over time. We’re watching new game classes form around us, and an unprecedented ability to reach and coordinate global audiences and participants, and I hope that this helps you look at this space with more creativity.</p><p>While I would be interested in contributing to an ecosystem like this, and it, I certainly don’t have the time to code the entire thing, let alone maintain and run it. If this struck a vibe with you and you’d want to band together to build something like this, please reach out!</p>]]></content:encoded>
            <author>wschwab@newsletter.paragraph.com (Will Schwab)</author>
        </item>
        <item>
            <title><![CDATA[Catblazer Chronicles Jan '22]]></title>
            <link>https://paragraph.com/@wschwab/catblazer-chronicles-jan-22</link>
            <guid>v2rpnxaZVdKuajy4NQSx</guid>
            <pubDate>Sun, 13 Feb 2022 14:51:03 GMT</pubDate>
            <description><![CDATA[The month of the podcast If you’re interested in learning more about the Catblazer Initiative, look here Let’s hop into what was going on in January.MirrorThis monthly report should be the first Catblazer monthly report that is published Mirror-first. Until now, the ECH has primarily published on Medium, and recently also tried out publishing some articles in tandem on both, but primarily referencing the ECH Medium. I was a part of the effort for working to move ECH over to Mirror, though we ...]]></description>
            <content:encoded><![CDATA[<p><em>The month of the podcast</em></p><p>If you’re interested in learning more about the Catblazer Initiative, look <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://mirror.xyz/wschwab.eth/LpY-jFqBaHslRMsoScdzAj80hEju07WwIF3pGXVAmOE">here</a></p><p>Let’s hop into what was going on in January.</p><h2 id="h-mirror" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Mirror</h2><p>This monthly report should be the first Catblazer monthly report that is published Mirror-first. Until now, the ECH has primarily published on Medium, and recently also tried out publishing some articles in tandem on both, but primarily referencing the ECH Medium. I was a part of the effort for working to move ECH over to Mirror, though we will likely continue also publishing on Medium. Big shoutout to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/trent_vanepps">Trent</a> for getting us our own $WRITE token - <code>ethcatherders.mirror.xyz</code> , which points to a wallet set up for the ECH to be able to publish easily from. Note that this is not the ECH multisig address - we wanted to be able to publish without needing m of n signatures, but instead will be a hot wallet set up for this.</p><p>I’m really happy to be moving us towards more web3-native platforms, and hope to see us doing more of this in the future.</p><h2 id="h-ech-podcast" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">ECH Podcast</h2><p>After months of talking, this is the month we finally launched the ECH Podcast. Coming on the tail of the Mirror announcement, I feel bad saying we’ve been primarily pushing it on Spotify - if anyone knows of a decentralized podcast hosting service and/or platform, please reach out (my details should be at the bottom of this article). That being said, we’re on Spotify <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://open.spotify.com/show/7dgxKMkSyy3HWtQW7OfqXA">here</a>. We originally planned on releasing every other week, but have managed to keep a once-a-week cadence to date. I’m not sure if this will hold permanently, but am happy we’ve pulled off this many episodes so far.</p><p>The episodes are 40 min-1 hr long interviews aiming for a more in-depth and technical angle. Part of the goal is to expose listeners to these incredible builders, and also to give everyone the chance to learn from their experience. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/poojaranjan19">Pooja Ranjan’</a>s excellent <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/playlist?list=PL4cwHXAawZxqu0PKKyMzG_3BJV_xZTi1F">Peep an EIP</a> series has made us realize at the ECH that we have a lot of room in producing quality educational content, and I hope this continues that trend.</p><p>So far I’ve been finding guests, interviewing, and recording the episodes, but that hardly means this is a one-person show. Pooja has been very instrumental in getting me started, and has provided editing for all of the episodes so far. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/zkDoof">zkDoof</a> has joined too, and has been helping me out with a lot of technical and scheduling support, and will likely also move in to start taking care of editing.</p><p>We recorded four episodes in January, though the last was only released in February:</p><ol><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://open.spotify.com/episode/05nC12SLljVrtKltbHjLef?si=9631570a412a423d">Innovative Smart Contracts with Andre Cronje</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://open.spotify.com/episode/3PCA0sJRz10NbXTTSXLkN4?si=21c63776d7ba4e8d">Nethermind Client with Tomasz Stańczak</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://open.spotify.com/episode/2baQnYpheB8ol9Kk9fMUCl?si=d388793d25344726">Finding Vulnerabilities with samczsun</a></p></li><li><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://open.spotify.com/episode/3ULiE90kOhP9MzWkrX0Trr?si=0b8b03faa96349ce">Rotki App with Lefteris Karapetsas</a></p></li></ol><p>Just getting this off the ground and running with it took all of my ECH hours this month. I’m wondering if this is something that will take less time as I get more used to it, or if as I (hopefully) get better at it will still take roughly the same amount of hours. I’d like to have time for other things too.</p><h2 id="h-other-initiatives" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Other Initiatives</h2><p>The ERC initiative I’ve mentioned in past posts has been largely quiet, though I have been keeping up with it. Supreet and I have been working on trying to design some emergency protocols for app-layer platforms in the space in the meantime. He’s doing most of the work right now, and when we have a good rough draft, we’ll start showing it to experts in the field, and after we iterate through it with them, we hope to publicize it.</p><p>Gitcoin’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://kernel.community">KERNEL</a> has started its new cohort, Block V, at the beginning of February, and I hope to be active there, as I have been in the past, as part of my onboarding efforts, though some personal stuff and the podcast might cause me to participate a bit less than usual.</p><h2 id="h-conclusion" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Conclusion</h2><p>I did hint just above that there is also some personal news - while I am still keeping largely quiet about it, I am in the process of moving jobs. I recently accepted an offer, and hope to publicize more details about once it’s more finalized. This has affected my capacity in February, but I should still be able to meet my usual hours for the ECH.</p><p>That’s it for the report for this month. As always, if you think I might be able to help you, or if you’re interested in helping, don’t hesitate! Reach out. I’m @William94029369 on Twitter and wschwab#7045 on Discord. I can also be found as wschwab on a number of platforms.</p><p>Until next month!</p>]]></content:encoded>
            <author>wschwab@newsletter.paragraph.com (Will Schwab)</author>
        </item>
        <item>
            <title><![CDATA[General End of Year Ramblings]]></title>
            <link>https://paragraph.com/@wschwab/general-end-of-year-ramblings</link>
            <guid>0wFWFfvsxnZF1MOLAfE7</guid>
            <pubDate>Sun, 09 Jan 2022 14:28:33 GMT</pubDate>
            <description><![CDATA[On feeling dumb, learning, and other existential crises. I&apos;m ending the year on a bit of a funny note: feeling like a moron. This happens to me periodically, and while it isn&apos;t comfortable, I&apos;ve come to really appreciate times where I feel like this, since they give me the inertia I need to keep on learning and growing. There isn&apos;t one particular thing that brought it on, more like a whole series of events where I felt very smoothbrained each time, and my personal time wei...]]></description>
            <content:encoded><![CDATA[<p><em>On feeling dumb, learning, and other existential crises.</em></p><p>I&apos;m ending the year on a bit of a funny note: feeling like a moron.</p><p>This happens to me periodically, and while it isn&apos;t comfortable, I&apos;ve come to really appreciate times where I feel like this, since they give me the inertia I need to keep on learning and growing.</p><p>There isn&apos;t one particular thing that brought it on, more like a whole series of events where I felt very smoothbrained each time, and my personal time weighted average has tipped me into just feeling like a moron compared to everyone else in the room</p><p>(spoiler alert: I probably am, it&apos;s a bunch of really smart rooms, and tbh, I wouldn’t have it any other way - I wholly endorse searching for places where you’re the dumbest person in the room on the topic)</p><p>This all makes me reflect on the strange ways people learn - I know for me I go probably go <em>at least</em> 10x faster if I have a partner, someone I can think out loud with and who helps catch the inevitable mistakes, or being able to just hang out and watch someone who knows what they&apos;re doing, which I think works even better, just I almost entirely don’t see this as a thing.</p><p>For example: I was a bit overwhelmed by the EIP process, but then <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/lightclients">lightclient</a> started doing these sessions where you could watch him just do EIP editing, and it took me a couple of months, but now I&apos;m beginner-comfortable with it, and have contributed some editing and even some ERCs.</p><p>Just being able to watch him go through the motions was huge.</p><p>I feel like people don&apos;t like teaching this way, and I admit that having a pleb on your coattails can slow you down, but every now and then I wonder if I could just hang out with someone doing advanced math (for example) if it would work better for me than my misadventures in the academic system. tbh, I’m not sure very many people out there like learning this way either.</p><p>I dunno what it is about me, if I see you do it a bunch of times and am allowed to ask the same stupid question that didn&apos;t sink in the first three times you answered it, I find that after spending a bit of time at y=0, I can start picking up quick. I guess if I’d completely nerd out about it, I kinda feel like most people’s learning curves are more linear than mine. When I’m feeling better about myself I like to think that once the curve kicks in for me I go pretty quickly, but in a space where every time Dave White makes a tweet someone implements it within a few hours, I kinda feel like that would be misplaced hubris rn.</p><p>It&apos;s like I need ridealongs or something, I dunno, but apprenticeship just doesn&apos;t seem to be a thing anymore (at least in the fields and interests I’ve got).</p><p>Another issue is that I&apos;m interested in like a million things at any given moment, makes it easier to give up when there&apos;s 1000 more things to try at any given moment. Getting better at defi, assembly, rust, keeping up fullstack skills, non-EVM chains, tons of tools and platforms specifically, it&apos;s hard to pick a line and focus on it, really put in through thick and thin, unless I have some kind of job dictating it. (I&apos;m fine when I have a job that dictates it, btw, I just kinda get nuked when the field is open and I have to decide.)</p><p>There’s so much awesome stuff out there to learn, so many awesome people out there killing it in each one, I guess I’m just pulled in too many directions and just get torn apart.</p><p>Strangely, one of the things that I think makes these times bearable as opposed to flat out rekking me is how many times I’ve been told before that I couldn’t make it. I have a collection of those. I’ve been told it was helpless for me to teach myself how to code at all, for example, or at least to get a job in it, by someone who places beginners in coding jobs for a living. Twice. Once when I first got started, and then, a couple of years later, a number of people I knew who all recommended this person nudged me to try again since I was more experienced by then.</p><p>I suspect this would be true for anyone - once you survive enough of your own obituaries, having a setback like feeling stupid isn’t catastrophic anymore, and the humility can even be welcomed. I’m used to feeling like I’m behind, and can even enjoy the challenge of breaking through to a new level of skill or understanding. I don’t even think it’s a competitive thing, I don’t enjoy going back to them and showing them they were wrong. It’s more like proving it to myself.</p><p>I don’t really do resolutions, predictions, or goals for new years. The world is too chaotic for it, imho, and I’d rather adapt to what comes than be stuck looking at goalposts that I don’t really think are relevant anymore. I’m not even sure if I can grok what the really important things that happened this past year are yet - it’s still too soon.</p><p>(Incidentally, this is completely unrelated, but it’s bothered me that things like the Oscars are held for content from the same year. People wonder how they missed major groundbreaking and generationally important films, but it seems clear, at least to me, that it’s because it was too early to tell. I keep on wondering how different the choices would be if, for example, the Oscars held this year judged films from 5 or 10 years ago.)</p><p>So, what does next year hold? Other than inversebrah inevitably revealing that he’s actually Elizabeth Warren, I hope it at least finds me a smarter and more talented person at the end of it than the beginning of it, and I’d certainly like to believe that there’s a good chance it will.</p><p>Y’all amazing, it’s hard to even imagine spending my day anywhere else in the codingsphere, see you in 2022.</p>]]></content:encoded>
            <author>wschwab@newsletter.paragraph.com (Will Schwab)</author>
        </item>
        <item>
            <title><![CDATA[Catblazer Chronicles - Nov '21]]></title>
            <link>https://paragraph.com/@wschwab/catblazer-chronicles-nov-21</link>
            <guid>WFgeJZOApzmPBPEhnLqi</guid>
            <pubDate>Sun, 05 Dec 2021 16:37:29 GMT</pubDate>
            <description><![CDATA[Photo by Stepan Unar on UnsplashLook here if you’re interested in learning more about the Catblazer Initiative. Let’s hop into what I’ve been up to over the last month.KERNEL Block 4I mentioned Gitcoin’s KERNEL program last month (and in other months). Block 4 drew to a close in November. It’s been a really incredible journey with KERNEL, as it always is. I put in more hours in some 1-on-1s and a group session over the month. The tremendous quality of KERNEL Fellows makes me continue to belie...]]></description>
            <content:encoded><![CDATA[<figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/47fa496cf66f09cc4d62faaf3114a89cd2eade15b0e7d319828db6565fba524a.jpg" alt="Photo by Stepan Unar on Unsplash" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Photo by Stepan Unar on Unsplash</figcaption></figure><p><em>Look </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/ethereum-cat-herders/catblazer-chronicles-july-21-2c0c22bc8827"><em>here</em></a><em> if you’re interested in learning more about the Catblazer Initiative.</em></p><p>Let’s hop into what I’ve been up to over the last month.</p><h3 id="h-kernel-block-4" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">KERNEL Block 4</h3><p>I mentioned Gitcoin’s KERNEL program last month (and in other months). Block 4 drew to a close in November. It’s been a really incredible journey with KERNEL, as it always is. I put in more hours in some 1-on-1s and a group session over the month. The tremendous quality of KERNEL Fellows makes me continue to believe that this is one of the best venues to focus onboarding efforts on.</p><h3 id="h-peep-an-eip" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Peep an EIP</h3><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/playlist?list=PL4cwHXAawZxqu0PKKyMzG_3BJV_xZTi1F">Peep an EIP</a> recorded 3 episodes over November — I was present for all three, and aided in preparing questions and handling portions of the Q&amp;A after the guests gave presentations.</p><p>In addition, I’ve been working on coming up with lists for potential guests and question lists for a potential Peep an EIP podcast spinoff that we’ve talked about in the past. I’ve been moving a bit slower on this than anticipated, unfortunately. I suspect some of it is finding the courage to pull the trigger and reaching out to people to see if they’ll come on, though I have already spoken with one potential guest.</p><h3 id="h-eip-championing" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">EIP Championing</h3><p>I’m happy to say that I’ve been getting more involved in actively contributing to editing ERCs, another topic discussed previously. Not as an EIP editor, I don’t have merge rights, but rather looking over new ERC submissions and trying to lighten the load of the active editors by making recommendations when ERCs don’t conform to EIP-1, and also trying to offer whatever other useful suggestions I can. I’ve been trying to take a chunk of time on Sundays to look at any new ERC PRs that have been opened over the week, and have contributed on both GitHub and the various Magicians threads.</p><p>I’ve also continued participating in lightclient’s excellent EIP editing sessions, and am happy to see some new faces there too, largely from Pooja Ranjan’s efforts to find more talent to help the EIP editors.</p><h3 id="h-erc-involvement-initiative" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">ERC Involvement Initiative</h3><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/suprgupta">Supreet Gupta</a> has continued his wonderful efforts in this, and I’m happy to say that we have the interest of some major platforms in creating ERCs based on their work. I’m very excited by this initiative, and see it as very synergetic with the other work I’m involved in with ERCs. Getting quality ERCs, and seeing these platforms contribute to the ecosystem in this way are both valuable imho, and I look forward to seeing more progress on this front.</p><h3 id="h-future-efforts" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Future Efforts</h3><p>I’m looking to keep up the efforts above, and also have a number of things to look towards in November.</p><ul><li><p>I would be very interested in helping facilitate the development of emergency protocols for Defi platforms. If you would be interested in being part of such an initiative, please reach out. (I put this last month too, still very keen)</p></li><li><p>I’ve (finally) begun sketching out questions for and reaching out to potential guests for a podcast spinoff of Peep an EIP, I hope to continue on this, and maybe even potentially begin recording this month</p></li></ul><p>This recap is a bit shorter than some of the previous months, but not due to my involvement being any less than in other full months — it’s more due to the topics being well described in previous months. I’ve gotten to the point where I can talk about onboarding tasks pretty quickly, but I still put in hours on it.</p><p>As always, if you think I might be able to help you, or if you’re interested in helping, don’t hesitate! Reach out. I’m @William94029369 on Twitter, and can also be found as wschwab on a number of platforms, including in the Ethereum Cat Herders Discord. (As a note, the Ethereum Cat Herders Discord has been moved due to a security incident, the new server has been posted by the official Cat Herders account <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/EthCatHerders/status/1467315864110354432">here</a>.)</p>]]></content:encoded>
            <author>wschwab@newsletter.paragraph.com (Will Schwab)</author>
        </item>
        <item>
            <title><![CDATA[Catblazer Chronicles June ‘21 ]]></title>
            <link>https://paragraph.com/@wschwab/catblazer-chronicles-june-21</link>
            <guid>cDe2dCZd3vOjT8l4oJd3</guid>
            <pubDate>Tue, 09 Nov 2021 15:21:01 GMT</pubDate>
            <description><![CDATA[Photo by Katja Ritvanen on Unsplash(This is a repost of an old update: I’m experimenting with Mirror in parallel to the Medium.)What is a Catblazer?The Catblazer position was created to bring more focus to external ops within the Ethereum Cat Herders. In traditional structures, a product or project manager can help a team internally by helping manage deadlines, allocating engineering resources, and more. They also help coordinate with points of contact outside the team, such as clients or con...]]></description>
            <content:encoded><![CDATA[<figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/df6912909c52644a6dc05583c5a9740e0cf19d1b294d0dcdad37cf1c8aa1dbf3.jpg" alt="Photo by Katja Ritvanen on Unsplash" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Photo by Katja Ritvanen on Unsplash</figcaption></figure><p><em>(This is a repost of an </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/ethereum-cat-herders/catblazer-chronicles-july-21-2c0c22bc8827"><em>old update</em></a><em>: I’m experimenting with Mirror in parallel to the Medium.)</em></p><h2 id="h-what-is-a-catblazer" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What is a Catblazer?</h2><p>The Catblazer position was created to bring more focus to external ops within the Ethereum Cat Herders. In traditional structures, a product or project manager can help a team internally by helping manage deadlines, allocating engineering resources, and more. They also help coordinate with points of contact outside the team, such as clients or contractors, or even other teams in the same entity in order to coordinate work, bring minds together to collaborate, and ensure efficiency.</p><p>The wider Ethereum space is a permissionless, decentralized space. Who ensures that communication? On one hand, there’s a tragedy of the commons, and occasionally information asymmetry: it means working on bringing people together and creating efficiency when anyone can do it, and it also means being in the know enough to do it. On the other hand, it’s a permissionless space — literally anyone can do it.</p><p>“Catblazer” is a slightly ridiculous cat-themed name, keeping with the hallowed branding of the Cat Herders. It also comes from the term trailblazer — someone who discovers and creates new pathways for others to follow. The idea is to blaze new paths in the unexplored frontier.</p><h2 id="h-what-did-we-do-this-month" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What did we do this month?</h2><p>A lot of ecosystem onboarding presented itself this month. Both through independent connections and through Gitcoin’s KERNEL program I spoke with people ranging from a 16-year-old who wants to launch a platform with its own token to a developer with 20+ years enterprise/commercial experience who wants to drop it all and jump into the space. This is also a part of Catblazing — not only helping existing people and projects in the space, but also helping people into the space in the first place.</p><p>I also worked on a survey for Ethereum (1.0) node runners commissioned by Nethermind. This should allow us to understand more about the mindset of node runners with regard to client selection, along with information on other related topics. If you run an Eth 1.0 node, please take the time (~5 min) to take the survey <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://forms.gle/vN5tiPEXiM2ftJaA7">here</a>.</p><p>I also encountered a startup trying to get more information on what data NFT platforms would be better served with, and helped to find them some people to interview.</p><p>I’ve been involved with the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/playlist?list=PL4cwHXAawZxqu0PKKyMzG_3BJV_xZTi1F">Peep an EIP</a> series since it began, and attended a number of this month’s episodes as an interviewer.</p><p>In addition, there have been a number of internal or otherwise very early ideas that I’ve invested time in. I hope to be sharing details of at least some of them in the months to come.</p><h2 id="h-whats-next" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What’s next?</h2><p>I’m still finding my footing, and expect that my main focus will change from month to month, but will still end up coalescing more over time into a clearer range of operations. I wouldn’t be surprised to learn that new items can present themselves unexpectedly and spontaneously. That being said, here are some things that might be on the agenda for next month:</p><ul><li><p>Looking for new tasks and specifically recruiting new ECH volunteers for them. Do you speak Chinese? Reach out! Do you enjoy video editing? Reach out!</p></li><li><p>We have some new and awesome ideas for the Peep and EIP series — hoping to lay some new groundwork on that in the next month.</p></li><li><p>EIP editing: there’s been a lot of talk around renovating ERCs and the EIP process, I plan on getting more involved next month</p></li></ul><h2 id="h-conclusion" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Conclusion</h2><p>That’s it for the report for this month. I’m looking forward to this journey and where it might lead. If you think I might be able to help you, or if you’re interested in helping, don’t hesitate! Reach out. I’m @William94029369 on Twitter, and can also be found as wschwab on a number of platforms, including in the Ethereum Cat Herders Discord.</p><p>Until next month!</p>]]></content:encoded>
            <author>wschwab@newsletter.paragraph.com (Will Schwab)</author>
        </item>
        <item>
            <title><![CDATA[Catblazer Chronicles Jul-Aug ‘21 ]]></title>
            <link>https://paragraph.com/@wschwab/catblazer-chronicles-jul-aug-21</link>
            <guid>SP2MLDAL26bOHHLFjFri</guid>
            <pubDate>Tue, 09 Nov 2021 15:18:17 GMT</pubDate>
            <description><![CDATA[Photo by Derek Story on Unsplash(This is a repost of an old update: I’m experimenting with Mirror in parallel to the Medium.) Well, it only took me one month to miss writing a monthly recap, so this will cover both July and August. On the bright side, a large part of this is also because there’s been so much going on. I’ll do my best here to recap what I’ve been up to for the last two months. Originally I was going to split this into two months, but a lot of the things I was involved with end...]]></description>
            <content:encoded><![CDATA[<figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/7f3535618430543544f2df35b55eac23659f45d58428ccc5189ffa0230a9aa10.jpg" alt="Photo by Derek Story on Unsplash" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Photo by Derek Story on Unsplash</figcaption></figure><p><em>(This is a repost of an </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/ethereum-cat-herders/catblazer-chronicles-jul-aug-21-899831e31d1c"><em>old update</em></a><em>: I’m experimenting with Mirror in parallel to the Medium.)</em></p><p>Well, it only took me one month to miss writing a monthly recap, so this will cover both July and August. On the bright side, a large part of this is also because there’s been so much going on. I’ll do my best here to recap what I’ve been up to for the last two months.</p><p>Originally I was going to split this into two months, but a lot of the things I was involved with ended up overlapping in both, so I’m going to keep everything together.</p><p>First, the Cat Herders were looking to make an <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/ethereum-cat-herders/the-london-upgrade-commemorating-e2b3a5daa8c7?source=collection_detail----cb99bef2c5dc-----0-----------------------">NFT commemorating the London hard fork</a> (or network upgrade, if you prefer that nomenclature). I was involved in the effort, secured an artist for it (<a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/spidertianz">Tian Yuan Zhao</a>), and was actively involved in some of the distribution efforts. I can’t take credit for the actual initiative — that was primarily William Xuan afaik, with Pooja Ranjan doing a lot of the internal work.</p><p>Onboarding continues to be one of my heaviest involvements. I’m involved in EthernautDAO and Gitcoin’s Kernel (both are not for pay, though I did receive GTC in the airdrop). We’ve made a group in EthernautDAO which I loosely manage, right now we’re working on a project idea from Dhannte. In addition to those efforts, I’m happy to say I get the occasional message out of the blue from someone just looking to get into the space more.</p><p>I didn’t have so much actual coordination work, though in one case I was able to get an economist who was researching GRT in touch with The Graph.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/hesterbruikman">Hester Bruikman</a> from Status is working on an initiative to make a wallet <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://en.wikipedia.org/wiki/Plugtest">Plugfest</a>. We’ve spoken about it, I’ve tried to help find volunteers for the initiative, primarily around comms at this point. We’re interested in getting in touch with any wallet providers, and also any wallet middlewares. The goal as of right now would be to coordinate a series of calls between wallets and apps integrating them to test and find common wallet integration pain points and move towards solving them. If you are interested in helping with this, please reach out to either myself or Hester.</p><p>I’ve been getting some tutelage from lightclient on EIP editing, and have been trying to lend a hand with more ERC proposals. Most EIP editors are more core-focused, whereas I’m on the application layer. One effort I’m proud of is some <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ethereum/EIPs/pull/3763">proposed changes</a> to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-712">EIP-712</a>. EIP-712 is one of the most used ERCs, but until a few months ago was still in Draft. One of the reasons is a checklist of conditions the authors placed in the EIP that must be met in order for it to be moved to Final. In my humble opinion, these conditions have either been met, or the goalposts have moved since their writing. (Fun fact, this EIPs <em>fourth</em> birthday is next week.) If you are one of the authors of EIP-712 (Recmo Bloemen, Leonid Logvinov, and Jacob Evans) it would be amazing if you could give a look and offer any feedback — let’s get 712 to Final!</p><p>I’ve continued my involvement with the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/playlist?list=PL4cwHXAawZxqu0PKKyMzG_3BJV_xZTi1F">PEEPanEIP</a> initiative, Pooja Ranjan’s project spreading high-quality educational content, supporting with preparing for sessions, and acting as a bit of a co-host on some of the calls.</p><p>I’ve also contributed a little bit to an NFT Standards working group headed by Anett Rolikova of the Ethereum Magicians.</p><h2 id="h-upcoming" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Upcoming:</h2><p>I’m actually going to be pretty disrupted in September, and don’t expect to put in as many hours as I would in a regular month. In addition to pretty much everything above, which should be continuing (onboarding, EIP work, a wallet plugfest), there are some other initiatives that we’ve been working towards.</p><p>We have been talking about ways to diversify the PEEPanEIP series. We have some ideas, but will likely not actually start a new initiative in September due to my limited capacity. If you have skills in recording/preparing content and are interested in volunteering, please reach out to either Pooja or myself.</p><p>There are other initiatives I’m slowly working towards. Some have to do with some ideas I’ve heard from Jamie Pitts of the Ethereum Magicians, others around general ecosystem involvement with EIPs and ERCs.</p><p>As always, if you are interested in volunteering in any efforts, or have any ideas of your own, feel free to reach out anytime. I might not answer very punctually in September, so please don’t think I’ve ghosted you if it takes me a few days to get back to you. I’m @William94029369 on Twitter and wschwab#7045 on Discord.</p><p>Until next time!</p>]]></content:encoded>
            <author>wschwab@newsletter.paragraph.com (Will Schwab)</author>
        </item>
        <item>
            <title><![CDATA[Catblazer Chronicles Oct ‘21]]></title>
            <link>https://paragraph.com/@wschwab/catblazer-chronicles-oct-21</link>
            <guid>ZqLhSVFNfXCiqe5B50rU</guid>
            <pubDate>Tue, 02 Nov 2021 08:30:46 GMT</pubDate>
            <description><![CDATA[Look here if you’re interested in learning more about the Catblazer Initiative. I mentioned at the end of the report on July/August that I wasn’t likely to have much time in September, and this was indeed the case. I’ve rolled the little that I was able to do into this month’s report.EthernautDAOEthernautDAO was founded by Dhannte and the Ethernaut himself in order to deal with the shortage of senior-level developers in the smart contract space. The proposed plan was to allow talented Solidit...]]></description>
            <content:encoded><![CDATA[<p><em>Look </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/ethereum-cat-herders/catblazer-chronicles-july-21-2c0c22bc8827"><em>here</em></a><em> if you’re interested in learning more about the Catblazer Initiative.</em></p><p>I mentioned at the end of the report on July/August that I wasn’t likely to have much time in September, and this was indeed the case. I’ve rolled the little that I was able to do into this month’s report.</p><h3 id="h-ethernautdao" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">EthernautDAO</h3><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/EthernautDAO">EthernautDAO</a> was founded by Dhannte and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/the_ethernaut">the Ethernaut</a> himself in order to deal with the shortage of senior-level developers in the smart contract space. The proposed plan was to allow talented Solidity devs to open up apprenticeships on the behalf of their places of work for senior-level devs from other fields who are looking to get involved in the space, potentially offering them positions in the protocols and platforms they represent.</p><p>I’ve opened a slightly less traditional group there. As a Cat Herder I’m not looking to employ anyone directly, but am using it for the opportunity to help onboard more devs into the space.</p><h3 id="h-kernel-block-4" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">KERNEL Block 4</h3><p>I’ve been involved in Gitcoin’s <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://kernel.community/en/">KERNEL</a> program since its Genesis Block, and have been involved as a mentor since Block 2. KERNEL excels at bringing in an incredibly diverse, talented, and creative cohort each time, and I’m honored to be able to contribute in my own small way. KERNEL provides an excellent chance for onboarding, both in being able to answer general questions in the channels dedicated to building, but also with the introduction of pods centered around the various alumni and mentors, and also individual onboarding sessions.</p><p>I’ve put in a number of hours in both group and individual sessions. I’ve watched many of the alumni over the blocks grow platforms, protocols, and more in the year and a half that KERNEL has been around, and believe strongly in dedicating resources there in order to help people get the support they need as they come into the space so that they’re positioned for success.</p><h3 id="h-cat-herders-onboarding" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Cat Herders Onboarding</h3><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/poojaranjan19">Pooja Ranjan</a> has created an ECH onboarding call which lets us meet people interested in being involved with the Cat Herders or in the ecosystem at large. I’ve been involved with these calls, and have tried to help people find their place either in the Cat Herders or in the wider space.</p><p>In addition, there are people who have found me through other means. I try to offer whoever I can the time for a 1-on-1 to see what I can do for them. If the rate of people asking for them increases I might not be able to keep up, but in the meantime it’s still sustainable.</p><h3 id="h-erc-involvement-initiative" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">ERC Involvement Initiative</h3><p>I’m happy to announce that we’ve begun work on an initiative that has its roots in suggestions from <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/jemenger">Jamie Pitts</a> of the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethereum-magicians.org/">Ethereum Magicians</a>. There has been a terrific amount of innovation in platforms building on Ethereum, but much of this has not been converted back into ERCs.</p><p>As the space grows there is an increasing need to have clear standards and templates for building in the space. If we don’t take our collective innovations and make them as easy to access as possible, then firstly it decreases the quality and interoperability across the space as builders all build in their own ways, but there is also another possibility. As we see major Big Tech players increasingly interested in the space, there becomes the possibility of concepts without clear standards falling into the predatory patterns that have been such a part of web2.0 if major platforms create standards that receive enough traction to drive more builders to their platforms.</p><p>This initiative will be looking to help platforms and other major ecosystem builders identify innovations that can become ERCs and to help them through the process. I am currently being assisted by <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/suprgupta">Supreet Gupta</a>, a newcomer to the Ethereum Cat Herders. We’ve started reaching out to platforms, and can add more resources if the initiative finds traction.</p><p>If you are interested in helping, or if you’re a platform interested in bringing some of what you have created on Ethereum to an ERC, please reach out!</p><h3 id="h-eip-championing" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">EIP Championing</h3><p>Speaking of EIPS, aided by <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/lightclients">lightclient</a>’s excellent EIP editor sessions, I’ve been trying to increase my involvement in the larger EIP process, particularly in the realm of ERCs. I started with a bit of a focus on EIP-712, an ERC that already has a large amount of traction, and is used in a number of other ERCs, but was still in Draft status as of roughly half a year ago. lightclient <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ethereum/EIPs/pull/3497">moved</a> it to Review, and I <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ethereum/EIPs/pull/3763">added</a> some motivation for pushing it to Final. I recently <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/ethereum/EIPs/pull/4383">made a PR </a>to move it to Last Call, and per the suggestions of one of the editors (Micah Zoltu) I’m working with one of the authors in order to try and make some changes so we can get the PR merged.</p><p>Micah also proposed that I take on some other ERCs in a similar capacity, championing them and helping them get over the finish line. The current state of ERCs often sees even popular and well thought out ERCs abandoned in Draft status, and we’re looking for ways to move the quality ERCs further along the process. I haven’t started work on this yet, but have expressed interest.</p><h3 id="h-peep-an-eip" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Peep an EIP</h3><p>And speaking <em>about</em> EIPs, I’ve continued my involvement with <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.youtube.com/playlist?list=PL4cwHXAawZxqu0PKKyMzG_3BJV_xZTi1F">Peep an EIP</a>, Pooja Ranjan’s content series focusing on EIPs and other similar efforts in the space. I’ve been lending my skills in researching topics and as a co-host since its inception, and continued over October.</p><p>We have some very interesting news to announce regarding the Peep an EIP series. Its success has shown us that there is a demand for Cat Herders technical content. The Peep an EIP series has found a very definite format for itself, relying on guests presenting a slide set on a particular topic followed or mixed with Q&amp;A. We’ve felt that we should expand our efforts and would like to expand to include a podcast focusing on long-form interviews on technical topics. I’ll be taking point in trying to identify topics and potential hosts, and also in the interviewing, and will be assisted by Pooja Ranjan.</p><h3 id="h-future-efforts" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Future Efforts</h3><p>I’m looking to keep up the efforts above, and also have a number of things to look towards in November.</p><ul><li><p>I had begun assisting <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://twitter.com/hesterbruikman">Hester Bruikman</a> from <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://status.im">Status</a> in organizing an initiative around wallets, wallet middleware, and wallet integrators, but had tapered off a bit, and will be looking to reinvest some of my time there</p></li><li><p>I would be very interested in helping facilitate the development of emergency protocols for Defi platforms. If you would be interested in being part of such an initiative, please reach out.</p></li></ul><p>As always, if you think I might be able to help you, or if you’re interested in helping, don’t hesitate! Reach out. I’m @William94029369 on Twitter, and wschwab#7045 on Discord where I can be found in the Ethereum Cat Herders Discord (I can also be found as wschwab on a number of platforms).</p>]]></content:encoded>
            <author>wschwab@newsletter.paragraph.com (Will Schwab)</author>
            <enclosure url="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/088ab64813b492b5a48ee402f08e3d7b3a94a54b2f9ce771c8f5efb2af6dd721.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>