<?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>Gyges Lydias</title>
        <link>https://paragraph.com/@mud2monarch</link>
        <description>undefined</description>
        <lastBuildDate>Tue, 27 Oct 2026 11:44:18 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Gyges Lydias</title>
            <url>https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/c54b02c6cf6baa19017eace740047da3.png</url>
            <link>https://paragraph.com/@mud2monarch</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Simple Observations about Asset Tokenization]]></title>
            <link>https://paragraph.com/@mud2monarch/simple-observations-about-asset-tokenization</link>
            <guid>hVN2mWnDNXmnkbUyQNSN</guid>
            <pubDate>Wed, 04 Jun 2025 12:47:12 GMT</pubDate>
            <description><![CDATA["RWAs" are highly hyped, but perhaps not as well understood. I hope these simple observations about "RWAs"/asset tokenization are useful.]]></description>
            <content:encoded><![CDATA[<p>DeFi has achieved product-market fit with cryptonative assets but not yet with traditional assets beyond U.S. dollars. Simultaneously, cryptonative growth has slowed after the memecoin fiascos on Solana in early 2025. To find new growth, the crypto industry should focus on the application of its innovation to traditional assets and markets. Here are a few observations about asset tokenization.</p><p><em>These are my independent thoughts and do not necessarily represent the views of my employer.</em></p><h3 id="h-tokenization-putting-an-asset-onchain" class="text-2xl font-header"><strong>Tokenization = putting an asset onchain</strong></h3><p>PYUSD is a tokenized dollar liability. The special part of the liability is the <em>token</em> part, which is its new form factor. The underlying dollar corporate obligation doesn’t change whether PayPal issues it as a token or as a Venmo or PayPal balance. Generalized, if you tokenize something of you value you’ll have something of value, but tokenize junk and you’ll still have junk.</p><h3 id="h-tokenized-money-market-funds-have-not-found-pmf" class="text-2xl font-header"><strong>Tokenized Money Market Funds have not found PMF</strong></h3><p>Tokenized Money Market Funds (”TMMFs”) have added ~$6.4b in supply in the past 18 months while stablecoins have added 17x that amount. This seems like poor performance for an asset class that’s supposed to be a drop-in replacement. Additionally, a lot of TMMF issuance is subsidized by chain foundations, which means the organic growth of the class is even smaller. Why might that be? Hint: it has to do with my first observation. What’s the difference between BUIDL and USDC on the asset side? Now how about on the token side?</p><h3 id="h-a-security-is-just-a-legal-contract" class="text-2xl font-header"><strong>A security is just a legal contract</strong></h3><p>Equity is an entitlement to partial ownership of a company. Debt is a a legal obligation for future repayment. Legal contracts are secured by the state, the rule of law, and a legal system. Are you unclear about what you own? Ask yourself if you own a legal obligation to some future asset or performance.</p><h3 id="h-a-token-is-just-a-smart-contract" class="text-2xl font-header"><strong>A token is just a smart contract</strong></h3><p>Because I learned about blockchain from Bitcoin, I didn’t realize that an EVM ERC-20 token is not a literal bearer asset in the way I thought of a Bitcoin UTXO. In the Ethereum account model, tokens <em>are</em> smart contracts that record each wallet’s ownership. Understanding this is key to imagining the programmability that can make tokens special form factors for value.</p><h3 id="h-defi-adds-the-most-value-in-the-worst-markets" class="text-2xl font-header"><strong>DeFi adds the most value in the worst markets</strong></h3><p>Thanks to Brendan Malone for teaching me this. A startling number of people want to tokenize stocks. Why? The U.S. equities market is one of the best-regulated, most-liquid markets in the world (perhaps surpassed only by the market for U.S. Treasuries, lol). The barriers are higher and the improvements smaller for U.S. equities vs. other asset classes. Perhaps it’s wiser to start with a market that is inefficient, fragmented, and antiquated.</p><p>Understanding truths about the nature of assets and tokens can identify promising areas of investment, research, and innovation. Hopefully this post has helped.</p><p><em>These are my independent thoughts and do not necessarily represent the views of my employer.</em></p>]]></content:encoded>
            <author>mud2monarch@newsletter.paragraph.com (Gyges Lydias)</author>
            <category>tokenization</category>
            <category>defi</category>
        </item>
        <item>
            <title><![CDATA[Hackathon project: extracting BigQuery table schemas for use with an LLM]]></title>
            <link>https://paragraph.com/@mud2monarch/hackathon-project-extracting-bigquery-table-schemas-for-use-with-an-llm</link>
            <guid>UUugcQjdZrHUo8ddXxxI</guid>
            <pubDate>Fri, 23 May 2025 15:41:52 GMT</pubDate>
            <description><![CDATA[Description of a hackathon project in which I made a free tool to make AI use more effective with Google BigQuery]]></description>
            <content:encoded><![CDATA[<p>At Uniswap Labs’ biannual onsites, we dedicate most of the week to a company hackathon. It’s a time to think creatively, work on personal projects related to work, and collaborate with others. This time around, I wrote a short script to gather and coalesce BigQuery table schemas into a text document for use with an LLM. An executable, source code, and a usage guide are available on <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/mud2monarch/personal-projects/tree/main/uni-schema">my Github</a>.</p><h1 id="h-the-problem-to-solve" class="text-4xl font-header">The problem to solve</h1><p>As part of my work, I regularly use LLMs to help with data queries. We have a broad set of high-quality onchain and offchain data stored in Google BigQuery, and I write SQL to access and transform the data into actionable insights. LLMs — e.g., Claude, ChatGPT — are very helpful for accelerating that work because they help me quickly iterate on my code.</p><p>An important part of using LLMs to their max effectiveness is ensuring that your prompt has the necessary <em>context</em> for the LLM. Most simply, if you’re asking an LLM to write a SQL query that roughly takes the form of <code>SELECT (column_names) FROM (table_name)</code>, you need to provide the LLM the relevant column and table names. If you don’t, you’ll need to edit them manually before running the query, which can be tedious.</p><h3 id="h-what-i-do-now" class="text-2xl font-header">What I do now</h3><p>You could verbally describe the columns and table names, but it’s pretty tedious. Instead, I typically provide the LLM a screenshot of the table schema, which shows the model the column names and their types. However, this has a few drawbacks:</p><ol><li><p>Most models only allow four image uploads, so this doesn't work for queries that requires &gt;4 tables, which is common.</p></li><li><p>The model has to “tokenize” the screenshot, which introduces some error vs. text tokenization (I think). This could lead to less accuracy.</p></li><li><p>Images are not “semantically dense” when it comes to the context tokens that they consume. For example, the image of a table schema I tested used 2,205 tokens while the text representation of the table schema used 668 tokens — 33% of the image. If you feed an LLM more tokens than strictly necessary, it will perform worse, all else equal.</p></li><li><p>While small, it takes a little bit of repetitive effort to find and provide the relevant table schema to the model. This is a small, but constant, annoyance.</p></li></ol><h3 id="h-whats-better" class="text-2xl font-header">What's better</h3><p>A new standard for providing context to models has emerged, the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://directory.llmstxt.cloud/">llms.txt standard</a>. An llms.txt file is essentially a compressed set of documentation, that makes it easier for developers to use LLMs to integrate the API. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.anthropic.com/llms.txt">Here is Anthropic’s llms.txt file</a>. Other AI tools like Cursor use similar concepts — you can define context in a ‘cursor_rules.md’ file that guides the LLM’s output according to your preferences.</p><h1 id="h-the-project" class="text-4xl font-header">The Project</h1><p>I wanted to write a tool that could programmatically pull schemas for any table in our Google BigQuery into a single text file. The idea would be to feed that single text file into each of my queries so that any LLM I use would have full information about the schemas and table names with which I work.</p><h3 id="h-what-i-made" class="text-2xl font-header">What I made</h3><p>Conceptually, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/mud2monarch/personal-projects/blob/main/uni-schema/src/main.rs">the script</a> is very straightforward. Google provides <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://cloud.google.com/bigquery/docs/reference/rest/v2/tables/get">relatively usable APIs</a> that help users identify and collect information about Google BigQuery assets — exactly what I wanted to do. At a high level, I:</p><ol><li><p>Intake the user’s arguments, which include some config details (credentials, output filepath) and the tables that the user wants to collect (lns. 98-134)</p></li><li><p>Connect to the Google BigQuery API and authenticate (lns. 136-169)</p></li><li><p>Every table in Google BigQuery is defined by a unique <code>project.dataset.table</code> identifier, so I iterate through the user’s designated projects, datasets, and tables to collect all table names (lns. 172-266)</p></li><li><p>Collect the schema for every table from the Google BigQuery API (lns. 269-309).</p></li><li><p>Write every schema to a text file, with formatting (lns. 314-374).</p></li></ol><p>For this project, I used the <code>clap</code>, <code>serde</code>, <code>reqwest</code>, and <code>yup_oauth2</code> crates for the first time <span data-name="slightly_smiling_face" class="emoji" data-type="emoji">🙂</span></p><p>And it works! Here’s a demo I made for the hackathon showcase:</p><div data-type="youtube" videoid="ytdzjhRwQzY">
      <div class="youtube-player" data-id="ytdzjhRwQzY" style="background-image: url('https://i.ytimg.com/vi/ytdzjhRwQzY/hqdefault.jpg'); background-size: cover; background-position: center">
        <a href="https://www.youtube.com/watch?v=ytdzjhRwQzY">
          <img src="https://paragraph.com/editor/youtube/play.png" class="play">
        </a>
      </div></div><h3 id="h-reflections" class="text-2xl font-header">Reflections</h3><p>I’ve already been using this file to accelerate my work. I can more readily chat with the LLM I’m using like I would another employee. Referencing “the blocks table” and specific columns and correcting work in natural language rather than writing SQL myself makes iteration much faster. Here are some reflections on the project:</p><ul><li><p>Using AI helps you figure out how to use AI better.</p></li><li><p>I think the context file I generated could save me up to 40 mins per day on analysis-intensive days (+ a good amount of mental overhead). That's about an 8% increase in productivity (if I worked eight hour days). While that might not sound like too too much, it’s being applied to a base where I'm already 1.7-2x more productive than I was 1.5 years ago. These improvements compound over time</p></li><li><p>A 10% productivity improvement for a typical tech employee is equivalent to something like $30k/yr including benefits. Capital investments on internal AI tooling seem well, well worth the cost.</p></li><li><p>I like writing Rust! As a beginner engineer, I don’t know all of the errors that I might run into. Writing Rust with robust error handling and strong types <em>feels</em> (at the very least) very secure and reliable. When I write and run Python scripts, I often feel like I’m just praying they execute if I return to them a few months later.</p></li></ul><p><em>You can use this tool yourself! </em><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/mud2monarch/personal-projects/tree/main/uni-schema"><em>Check out the ReadMe and Usage guide for more information</em></a><em>.</em></p>]]></content:encoded>
            <author>mud2monarch@newsletter.paragraph.com (Gyges Lydias)</author>
            <category>ai</category>
            <category>llm</category>
            <category>bigquery</category>
        </item>
        <item>
            <title><![CDATA[A lightweight introduction to TEEs and how they’re being used today]]></title>
            <link>https://paragraph.com/@mud2monarch/lightweight-intro-to-tees</link>
            <guid>UkUrpZ515AMP38PRZ5w1</guid>
            <pubDate>Thu, 15 May 2025 12:27:12 GMT</pubDate>
            <description><![CDATA[Explanation of what a TEE is and how it can be used to introduce verifiability in blockchain systems, with code examples]]></description>
            <content:encoded><![CDATA[<p>One of the most exciting areas of blockchain innovation is the use of “TEEs” to introduce <em>verifiability</em> in important systems. A “TEE” is a special kind of computer that has an embedded private key. The computer can use the private key to make verifiable attestations about its behavior.</p><p>As discussed prior in this blog (see <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://paragraph.com/@mud2monarch/disaggregating-decentralization">Gyges Lydias: Disaggregating Decentralization</a>), verifiability is one of the key goods provided by decentralization. In this case, even though a TEE may be run by a single party, it still provides valuable user protections worth pursuing.</p><p>In this article, I lightly explain what a TEE is and walk through a new initiative by Flashbots and BeaverBuild to introduce verifiable priority ordering within L1 blocks. We will:</p><ol><li><p>Learn how a TEE introduces verifiability</p></li><li><p>Explain the Flashbots/BeaverBuild initiative</p></li><li><p>Verify one component of the initiative (priority ordering on ETH L1)</p></li></ol><p><em>These are my independent thoughts and do not necessarily represent the views of my employer.</em></p><h3 id="h-how-a-tee-works" class="text-2xl font-header">How a TEE works</h3><p>A TEE is a special computer processor, typically manufactured by Intel, that contains an embedded private key. For modern TEEs like Intel’s TDX, the TEE is functionally the same as the CPU. The CPU can be made available in cloud environments like Google Cloud or on bare metal providers. "TEE" stands for "Trusted Execution Environment" because users can trust the chip after verifying the attestation as described below.</p><p>The private key in the TEE is used in the same way we use private keys everyday: to prove the authenticity of some claim through a cryptographic signature. When we connect to our bank account, our browser authenticates the HTTPS connection with the bank’s server and verifying that the internet traffic is encrypted. When we send ETH to a friend, our wallet is signing transaction calldata with our private key which tells the network the transaction could only have been signed with our key.</p><p>For our purposes, a TEE produces a verifiable attestation by taking a “measure” of the virtual machine and programs deployed to the TEE, including the operating system kernel and all software loaded in, and signs and publishes an attestation of the hash of that software. You can think of this as putting all of the code into a string and hashing that string to produce a unique, deterministic, shorter signature.</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/1c6910cdfb2f857be10bc0da79dee98f.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAASCAIAAAC1qksFAAAACXBIWXMAABYlAAAWJQFJUiTwAAAFKElEQVR4nI2Uz08aaRjH578w2Z68eNmTh53DhktPdA9c1njag8nu2m1r2jQ9tGZtqWnZrdVsm7LEan+ArUUERBTHoVMzw8sAMoAMMDgjhYEWxx8w2jog4tigbGDUmCZN9pMnb97M4fvNO9/neaD61xw1q+5yuQAAwWCQZVnljmEYTdM8z9e/Te2w9tUX6ET09KzLslyv1zUaTWtra0fHzyqVCoKgtrY2lUql1WoBAP9f/dTgmL3d8tO/r4bBnOJ3eHT04uVLu90GADCbzaVS6VvSCIH23L5mtI/9eutiz93rv1zv6n9yr1qtNgwq5c+5VDSXot8zVC4V9WOTSwG3kOOE3DIT8W6uC4oETdMajUZ53FlW1wVAecmIz4rYzU7Lv6+Gp1AnQqCR5SVAkcXtIiTkljeFVFkSSzvrpZ31/erOfnWnLBXKklhYS2dTCZ7PCoIgiqJer6dpWmhCNxEEAVAkn+eL28W14sZacUPaLRW3xS3pk7RbWituJFJJSMhxZamwX5X2q59PquGxX5VqtSritGIYplarz507B53Q1tam1WoxDPORvmHjSEWulPfK0m5JOZXL7l5F2pWiDA3lUjTPUStxkGH9TBhjwhgXJzJcIJXwc3HCYX1tMo39dOHC+fPn1Wq1SqVqb6LT6Wads/PI/MMnQ6FkhAgBigmTER9OeSgmHEpGcMpDhIAv7IeWlwATxjZWky7zoMN032UetIz2ke6xrUI6SNhyKXpHKhWLBZ7nRVEsNZFlWRTFyPJSqVTCvAsW1LbxafOl45VuZMCC2rr7rujHDRW5gpKYZWYSii2+I7E3W4X05DPt6MClkYHfjY+ujT68vJ6PB/HJdDJUr9fVanVLS0tvb29HRwcMw52dnS3ftUCt0Ja0DShyErWnBd6Bz94a6ns+ZXr8Wq8fN/BrWZzyTLtnoHQyRBEOJoxluECGC6xm43k+mmH9K3FAuIwrTKhQFJVgRfH4IggCy7LZD43wMe8CTnkm5q0W1DY8MTL04tEjk/6p5bnBPIIAlAgCKMUsLvlngrgl4pvm4kQihHpR05J/JhF2L+IT01bT3BzS3d2tVqu/bwLDcFdX19TUFM/zAAAlAzbLWVAb6sdQP+bAZ524a+PTJk55zE5LIwPK40Btjw33fxs33Bwd+GOwt3N04NLsmweJEGobf/bu3YJGo4FhuL29vfWEoaEhV5M7Oi1JB5hM8tZQX7/hr36D7vKdq/0GnWJgtI8dd1Gej3FxgovhK3GQ52MZLsBzVNTvSidDO9JxsLIsC4Kg1+uVOYgsRURRdAMMIVAEoDhFIMCNUx6lEIAuBHHU87YxBytxb9Mj2mjWpnSej+b5GPl2XAlZUVfGuKenh2XZ083jBpjSnVa3AyUbBghAG7+LdKMk1shAyC0nwm678a55pNdlfvjinyuW0b7ZNw8so70R33Q6Gf5qN/A8bzabAQAmk4mmaTfAJuatFbnCZrmLt69o9fduDv7JZNjDoyMn7nK4nY0XcDE8FnQC1BijZgFq9KKmiG96EZ+IkA4hx51VV6vVEATBMHw61T/8CJO0n82usFmOpP0kHaCYMJvlPm5+xCkPoMiGQdQ/x3NUKuGPBhAmsrAS96YS/jwfJVzG4nru7A7X6XSn0jAM37hxA1vAUBKzow476kBJDCHmrYjdaB9rnq+zqx+gLwcHO9sFcSO/9iGVS9HpZPg9Q71nKCHH7ZWlLwcHZ1+gJHE6z0oSe9W9w6PGbq8d1k7TkmV5d69SO6z9B5KRG/VVMNPRAAAAAElFTkSuQmCC" nextheight="948" nextwidth="1646" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">Rebuild the same machine locally, produce an attestation, and compare it to the remote attestation to verify that the same code is running on the TEE.</figcaption></figure><p>To verify the signature, users, e.g., you and I, can rebuild the entire kernel and software from open source code and produce a hash of our local build. If we can produce the same hash provided by the TEE operator, then we know we have have verified exactly what software is being run on the TEE. This is very similar to how we verify open source smart contracts today — we compare the deployed bytecode of a smart contract, which is available onchain to anyone running a full node, to the source code provided by the publisher. If the bytecode of the source code matches that which is onchain, we have verified it is accurate.</p><p>In sum, using a TEE provides the quality of <em>verifiability</em> — an essential benefit of decentralization. If we can reproduce the hash then we know the source code we see is the source code in use. And once we know the source code that is in use, we can review the code to see exactly what is happening.</p><h3 id="h-flashbotsbeaverbuilds-buildernet" class="text-2xl font-header">Flashbots/BeaverBuild’s BuilderNet</h3><p>Flashbots is a research and development organization focused on mitigating the negative externalities posed by MEV. It develops and operates MEV-Boost, a key component of ETH L1’s block building system that processes ~90% of ETH L1 blocks. BeaverBuild are one of two major ETH L1 block builders, and they also run a powerful “searching” operation, which means they compete to arbitrage economic opportunities on ETH L1.</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/7aff48bef5432647df30c4b91ed2d9bf.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAQCAIAAAD4YuoOAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFT0lEQVR4nF2UC0yTVxTHD08RgT4opeWhAydgsTqGoDinUtCu0DLFtrrFxM1kJi5L5tyGxIwpD0FFB4NJXWQagSBTTIwyjDMygRawtQ+6lhYotbQVpC/aSmmspd/yFcI2T05u/vd3T87Jd869HyAI8srlUqnVsoFBpUgsFgjEAoFSLBlRyOVCkVImkQmHhp7whf0CqeipRCAQ9vbJBoZE/XyJYHB46Kmonz8uk2k1E+PjYzKp9G+53O2eR/zmW1jwLSyAD0HmZ60dJ77ZBLARgAqQAcFZEJUDmEwIzIJVGRC2GSATYDMEZAK8B7AJ3a7IhKAMCNzoJx3lZ3uGRwWDApFEMj4xodXr5UqlzmBAEATQL5iZvldVuyctd0Ny/A4SdefqtFzs6p24JAaE7YGo/PDUzLTI99MI25Ljtq6Jo2TEb6Gsy41fuzU5/sPIhJ2x6duCSLe+Oiq+297T3t77+80H16/fvXKl//bt5wN8i2YcrA7Hy9GxlooKKjc7loFPycYH7sPG5a+iZqzaFg2bE+CdXWFwiABcHOqcCOCGryyMDC7GxNAj12dFkGmYxO1RTccOtVeW3jhVdu1kaesPZbcqKzoqK7uqq4eafwO1RqOXK/5su4o7Qk5khQAnCrjRwMGHMTEhTAzsjQIODiVsPHDwqP44El05eH8YEdV7Q1tPHudfvfHo5s2/OjruNTffa27m37nzqLXVptfB7NyceUzza9Wp2MOrN7BWABu7lAhNgYP9GOD4CdtPOFiU7McuBaAcC/SgO/XnVWMGq8OuMxr7BgZ0RiM6ZP+o4bnRoJcruq/xvjiy9kRR5F429mtODJ1LwHBjcFx/Zz4hpBwkwqfE1IMECjcaw8VTuATSAWIONyaHSyAfiM5ghj6uq1FK5VKplN/PFwqFOp3OZrNZrVav1wvG6Wmjeuzxhap6BvZsDpzbATXb4cyu4M/zg4/mB++jBTLyAk7nhnyWF3I8L/gULehLWsCPuSHHdodU7go6Qws6mhtQkgWPaspVKu2zZyKBQKBSq1Vq9ejomFardbvdYDabLWZrV015aTKUJKJemgzL+vu4JVGSCCfXLJH/wpJE+JYEIw/va6ZMwzJJb1+fQDDgcrkWnwLaIoPBMP/a43w5eYVLvlxMaGLH8NjEJi6Jxybz2MTLxTgeO5bHJjdxSX5IvFxM4LGJfo/lsWMXA5wmjdWhFz0TKxQK2fCw3qBXKBR2uwMt8Mbj8fp8atGTmgJSGZ1cXwgNrPAGVtjiWscIrS8M+blwZQMrsoEVUc+IqGOE+o8i/CS8jhHayMJPTyq0ToNWM6FSq0dGRlRq9cDgoFarRQugDxpBZsZktUXxO7ZkHaZRT9BTTjOTyplJ33307tnChMM0allB8sUi8sUi0k/M6JpC8nkmuYK15lJRQllB0vkCXGPRSuuk6rlOa5oxOex2oVCkUChG/DZjMoHX60UQRKfTrcv8ENbSIaUIKCxYz4D0AljPhBQapLIgnQmUPKDuBioNUvOBQgcqHSh7IL0gOv2DrdnZKpVaLFdLpZLBwSGxWKwcUZrNZq/fwOtF7+voxGR168NfOnsutXVdaOlquttb29Z9ruV+Y2fPxdaucy1djZ09F9oeVLd2+0X3hbYHjZ1Patu6q278UXurz2q1zFn0JrNlxjQzNTXl8Xj+HTKCIHa7Y3RU7bRb3e55i3kaQZB515x5BhWv3fNOu/Ut4bBZEMTn8bx22Cy+hYWlf+dyyv8bWsDtdhsMhlcu1yuXy+F0IgjicDoX74DeYFwkxhcvloVtdtYvpmyzsz4EeeNv8nKltwr8A99yPk2pndEzAAAAAElFTkSuQmCC" nextheight="962" nextwidth="1890" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">BeaverBuild typically builds ~35% of blocks. From mevboost.pics.</figcaption></figure><p>Builders on ETH L1 construct blocks, which they send to validators through MEV-Boost. Because they send full blocks to validators, builders <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://decrypt.co/298176/tornado-cash-dev-charges-dropped-sanctions-illegal">have significant control</a> over which transactions are included on ETH L1.</p><p><a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://buildernet.org/blog/introducing-buildernet">BuilderNet is a new initiative</a> to build a distributed system that will decrease the control builders have over transaction inclusion and other important characteristics of ETH L1. The general idea is to construct a more verifiable, fair, resilient system that still offers competitive economics to profit-maximizing validators.</p><p>In order to achieve strong economics for validators, BuilderNet makes certain promises about how transactions sent to BuilderNet will be processed. For example, a user can send a transaction to BuilderNet and receive a rebate if her transaction generates MEV. Importantly, though, the user needs to trust that BuilderNet <em>will</em> provide the rebate prior to submitting her transaction. This is where TEEs come in: by running BuilderNet within TEEs (many of them; the system is distributed), users can verify that the code being run <em>will</em> provide the rebate that is promised. Hopefully you can see how the introduction of verifiability on arbitrary code expands the design space for decentralized systems.</p><h3 id="h-priority-ordering-and-censorship-resistance" class="text-2xl font-header">Priority ordering and censorship resistance</h3><p>Most people think of the value of censorship resistance in the context of a nation-state conflict: perhaps a powerful country like Russia wants to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.coindesk.com/policy/2020/07/15/russian-activists-use-bitcoin-and-the-kremlin-doesnt-like-it">censor payments to dissidents like Alexei Navalny</a>. But it is also important for a more benign — but still important — application on blockchains: fair auctions.</p><p>One way to mitigate MEV is to use strict priority ordering: transactions within a block will be ordered based on descending priority fee paid by the transaction submitter. Because only one transaction can capture an available economic opportunity, priority ordering amounts to an implicit auction: the block builder is effectively ‘selling’ the opportunity to the highest bidder. For a more eloquent explanation, see <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.paradigm.xyz/2024/06/priority-is-all-you-need">Priority Is All You Need by Dan Robinson and Dave White</a>.</p><p>One failure mode for a priority ordering auction is that the auctioneer, i.e., the block builder, is colluding with a bidder — or, in fact, is a bidder itself. This is not theoretical: this happens on ETH L1 today because BeaverBuild and Titan Builder are integrated searcher-builders. In this failure mode, the builder might position their own transactions ahead of other searchers’ transactions. This would break the priority ordering auction which would render the mechanism almost useless.</p><p>By running a block builder within a TEE, as BuilderNet is working on doing, searchers can verify that BuilderNet <em>will</em> order transactions by descending priority fee. If searchers can verify that the claimed behavior will actually be followed, they will be more likely to participate, and the system will be more efficient, with welfare accruing to all blockchain users in a well-designed system.</p><h3 id="h-how-to-verify-buildernet-is-ordering-transactions-by-priority-fee" class="text-2xl font-header">How to verify BuilderNet is ordering transactions by priority fee</h3><p>As discussed above, there is a two-step process to verify the behavior of a TEE:</p><ol><li><p><strong>Rebuild the TEE locally and compare your local attestation to the attestation provided by the TEE operator</strong> → this allows you to verify that the code that the operator claims is being run is actually being run</p></li><li><p><strong>Examine the source code you built locally to see what it is doing</strong> → this allows you to verify that the code is doing what the operator says the code is doing</p></li></ol><p>We’ll leave the first step to a later exercise, but today, we will audit the BuilderNet code to see if the code orders transactions by priority fee.</p><p>Flashbots <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://buildernet.org/docs/os-services-builds#key-services">claim that BuilderNet uses rbuilder</a>, which, if you’re at all familiar with the typical naming conventions of Rust aficionados, is a block builder written in Rust. Again, we can only verify their claim by verifying their attestation, which is out of scope for this exercise. The rbuilder code, however, is <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/flashbots/rbuilder/">available on Github</a>.</p><p>I will now attempt to explain Flashbots’ code in natural language for someone unfamiliar in Rust. Rust is pretty… f&amp;<span data-name="robot" class="emoji" data-type="emoji"><img src="https://cdn.jsdelivr.net/npm/emoji-datasource-apple/img/apple/64/1f916.png" draggable="false" loading="lazy" align="absmiddle"></span>ked, for lack of a better word, so bear with me. I’ve stripped out a lot of the code, but I share the filepath and code line for each block if you want to read the full thing. For those of you who know Rust, the terminology will not be correct, but I hope you will agree it is accurate.</p><p style="text-align: center"><em>The code that shows rbuilder uses priority ordering</em></p><p>We enter the block building process through the <code>build_block()</code> function. The function has a different behavior based on the <code>OrderPriority</code> parameter we use (that’s what the <code>&lt;OrderPriorityType: OrderPriority&gt;</code> angle brackets mean). Remember this.</p><figure float="none" width="621px" data-type="figure" class="img-center" style="max-width: 621px;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/26f19e31cb0ee34ae992f578eabc7626.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAOCAIAAADBvonlAAAACXBIWXMAAAsTAAALEwEAmpwYAAACwUlEQVR4nK2T208aQRTGP3AhFouACAjCOnIvICAICqvWPtQX25j0qc/9r2rTJxN91PhSrLVJ0xgMpgkQKdpUixGrQsWSEI2XZppZUFPTi4lNfjn55ttz5uyc3UGF0vIZPThnlM9o+fR/cNbYrUIpyqd094jm945TG5X054Psl8oNSf/JL1RWi9W1/aOvx/TbKUXphGa2q2Pjz8YeP+x6NNp6b1jtuX8bNL4RhSMWHH1a74GdGl1aLZhdgsrEw2KF1ALuV6Tm685vuUrjAWOLrT+VLxZrFNtVuriSV7oHIbdC74OxB3oPDB4YvEwYe5gweBuCOWKOKXBhig7TYqwXat2tTuFd+tPWIcXW4fl8MtvqFKDsRrsLajuLbQ4WlVbIu6AgUHSJXIrLJWE517FBamm29y+mPm5WfrAGiWRG7Rag8kDvh8EvniPA6Agy3e6BzseExsUcnR9aL6PNBZXtLw3eLOcaDV4lMzrvCHQBiTkCEgcRYB1qssZhHQI/AFMfOqMgg2x3IjBt6oMpAqOfHbTF9u8GiWT2rmMA0k7xcTfa7FBZ2dspeMgtkPMNwVnEaGZL5vBQilNSEDZJOS9GcWjXGswnsy3OOORExkelfBQkAj4q6Y7dcQhN1riExDibABIDiclsgsw+jM6QhESlbDkoITHovTCGGhh80DjBWRSOgcWU2KBQpa+XV9XOOGBuzFfjYULfywp0flEHL+hFR5glaL3QBRqmysU+HssMQOtmB4KxmfS9XclvHZ6z3/R9ZtPz4AlHwjIS5khIJsJ1BTk+yJEQR0JyEpCTAHNIiOODMpZ5ZdarRMEKm20RjoQdQ+PJXGG7Kl60XPF7Yik7ObPwcnpuYmr2+dRMnYmp2ZtzWfJiem5ydiGRzOSK1Z0axf4JLVTp2l4tvVFaWd9Nre/ckg/ru+mN0tperVClpRP6E/Qy/VGQIwx/AAAAAElFTkSuQmCC" nextheight="744" nextwidth="1700" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">Entry point to block building, calling fill_orders()</figcaption></figure><p>This kicks us to <code>fill_orders()</code> immediately below. In <code>fill_orders(),</code> we loop through all the “orders” (i.e., pending transactions) that can go into the block.</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/85e0d99d926d89dc51ce936801439f65.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAaCAIAAABZ+cloAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEOUlEQVR4nK1VS2wTVxS9Mx7HiYPtyvVnhpnJuP7MjP/jsd0kDs4HSoQUIbpJumBdq6jdFZCyaVdFXXVDm36yog2J2i5QUhYtS9pFNkgsAptIUBekSJEbEYRQpJJMdd8bfyj5oUY6urrzZuadd+899z5Y27LWt6yNHevvf6zGztFgY8d6YuG2a1sWrG1Zdx40vpj98fPZuU+ufv/p1WtHgR8++2bhzoPGOiW4tnQ7yiek/gR4FHBI4JSPBHM3byNBfXP7u59+g3Aa+JxDKTFSASQDrWgwcpGRCmjlIiMWWNlkZZOjiwSsbFILosHJRRANCKQgRBDUZ3/+9fFTC/7c2J6ZX4KADuEk0gSJDSchoEFAJdDAn2j6Kn65HzQb/sRXC0t/bW4jwZdzN4DPM3IZRBOUATZSccSGQCqCUASpDHwe+gZALINYAqHQ5D4INsELSrAI4Sz+L5W52AnurSEudgK3FkugVEDIQ98g+shhYnwYEAmrhQMIri/aH/EkP3wKESRJC5DAg02Ek5hDPmtbTGaaPJLk+OnWuxIEVAilnZGyM1Jm5KIzio4r1s/IRYdSwvVouSc2gPUUcgg+izacRisa6IRSNn0wuWcEjGSAmIfjGYdkMmKekQxWMhghg4tCjpUMEDKMmAfRcKB+DFsRrYCELFo+u2sEerdS8SWqHnXEl37HrQ674lWfPtYdr3Srw73aaK826lZH3NqIM161j0xP+nLe965BQGfFEiMUWLnMxYa42CAbqbCRflYuoSU+KG+TUpdaZzy0ipBAswv1HwRfXmxrZrePbegQSL5CENSBz7KkgbGHRQOEHLVAVloOWcy032KFSOXwA1Iq2UQR7hIBT2VAFUm7WrerR4GaIeIRcvtF0OySzka70dVXflMb8+mnPMmTXYlqV6LKKQMupR9ZcbAkkRuFSKZIOP2anXx9EUJptm+Qi48x2MPF3tioOzri1k5z8WFQKly8CsfznU30+gR0igWTmFMqbTymDiHaQcQ/zAjak8DeQreHrT0kNHuOHubIB0WgI4do2PUUMpj91kiwnZafaj6SQFsqoHGLeTyiP/6KTIUMXjXIkSJCxAnBSAXb51P4J7WiwZILh2qXoX8RmdIRgo8BbWZ+sYOAz7FCgeFzOPEFEyGVQTLxVhAL6AsmOjiuM3Y32boi041cYe1BS+6MNsHM/BIrmsfUU15t3JOe6FJP9uhnfMa5NwrverNnfca5Y5kJlz7uyZ7tzUz06OMudaxN0+7eTh8dO0X1Jy++nv8FvFHwquDXIZBGx5cAn4YXrF9H4IrW4WTBGwd3dD90K98u3Hz8dAcv/VvL92vTV85/OD114dJk7eJU7RLFZO3iJFrqt19Nvv/x1IXLe+G9Dy6f/2i6Nn3l1vJKfdOCR8+s1fXnK/XG8r2Hv99d/f/44+7q8r2HK/XG6vrzR8+sfwGJ9oigR6kZTQAAAABJRU5ErkJggg==" nextheight="1600" nextwidth="1936" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">fill_orders() trickles down to PriorityQueue.pop()</figcaption></figure><p><code>PriorityQueue</code> , despite what it’s name might indicate in this context, is a non-Flashbots-specific function that implements a very high-performance data structure for sorting things. It is an open source and widely used primitive. In <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.rs/priority-queue/latest/priority_queue/priority_queue/struct.PriorityQueue.html#method.pop">the docs for that data structure</a>, we see that <code>pop()</code> pops the “item with the greatest priority.”</p><figure float="none" width="498px" data-type="figure" class="img-center" style="max-width: 498px;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/8cceea151f47ed667f72946c31b22715.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAICAIAAAAX52r4AAAACXBIWXMAAAsTAAALEwEAmpwYAAACaklEQVR4nH2NTUsbURSG79JN0V1LF+IXmsVYOsZJ6linqYm9pjc20Wag135BhDLU6aIILTaLziar/oDC/ICCm2wsglDclm7VEFA0g8nQJJPM5MuJ8wG3mJRoN30Wh/e8HM4DbNshxDVNTdNyOeXQNMuOYzRbRUXJmKZWq+Udx1CUzP7hT9MsNVvFakVp1NVqRXEcXdNyhbOsZVcKZ1lNy1l2xbIrzVaxVM5ZdlVVs4X8CSiVyhsbIgBgeAwMjoL1d4Fo+AYK3wQdXrz2j3kuw5Rv4Kv89v3H8If1pUEAEDu+6B8LBYbDM+M/dr4k4rPLUeq39r1U3Tk8+hZcmUHP50eogc+fREAIOTk5ymR+mabebhumqVe0U01TCupxQT22HUM31Hq9aNRK3QProm5oqus2u8cNo9wwiu220WxorntuOw3XPW+3a457ni9kC/nTSwEhpNVqBR48nJy8c3+WW15+ynGBhdCCz3cvEllaXX1569ZtjgvQtDcSWaJp7zTDxGIrDOMLBhcmJjwQLnJc4Ek0NjI8urb2hqa9fv+Md2pa13VCyF+BZV0kk5vRaBRjLIpiPB7neR7jZ686QPgomdzkeR6hx3NzczR9VxRFjDHP8wzDYIwhhIIgSJKUSCQ8Hs98h4OD/SsBIQRCyLIsxji8GGZZFiEEIYzFYqFgaGhoiGVZhmEkSUII9ff3Cx0wxt2SoiiEUCqVEgShr6+PoigI4d7e3j8CmqYRQhRFMQyDEMIYsywLAEilUoQQ27Z7sxt6ubdeb3pcCdLp9NbWliRJsiyn0+nt7W1ZlkVR3N3dvf7x+q9e/o/sDzbl4FGqh1VEAAAAAElFTkSuQmCC" nextheight="266" nextwidth="1032" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">PriorityQueue::pop() pops the item with greatest priority</figcaption></figure><p>Okay, we’re popping orders off a stack of block orders that sorts the stack based on “the greatest priority.” Now, we need to check if that priority is based on priority gas fee in our specific implementation!</p><p><strong><em>If we setup our block builder with OrderPriorityType of “OrderMevGasPricePriority” then we will pop orders based on priority gas fee.</em></strong> Let’s move over there.</p><p>The <code>PriorityQueue</code> library lets developers define the behavior based on the developer’s implementation of <code>cmp()</code>, which is short for “compare”. So Flashbots need to define comparison behavior for their specific use case. Let’s get back to rbuilder.</p><p>And we find the money line:</p><figure float="none" width="561px" data-type="figure" class="img-center" style="max-width: 561px;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/74e3dcc93ecb732ea87d66e5aa0d44a4.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAANCAIAAABHKvtLAAAACXBIWXMAAAsTAAALEwEAmpwYAAACXUlEQVR4nKWTy08aURTGj0qmCCEGpWN9FEfuvBCapolQUIol2NTu+p81cWXSuMWVCxc1tjam0RKsNhWoCW4gINL46hDNbLAmx5wZmKDWFckvN9/97uPc+80d0BDPrrCOhIb497pTzv5Ra26rIcL5FdZ0/FE8/Zotb2bL33KlDtnKlb//PvxVPK/peH6FcNrAnyUtHn+fnJ3sjYWAD8BQEAYDhCXudNvF/TlDz8Atj4bnsmXtpIHwR8fNXOmxNAX8GIwo4BLBxVr4jNZ0fPcQ2zQDZ5vmxpxiZCtXOtIRqhf4ZXvfIUXA5gWPH3g/9EvgkYFXwC2T069Qd3AC+BbN807Q5MFA0zHXmngUpzz1ObNfvUCo1K8/pbNuNd4zEgZvBHwzBnHwRkGIwXAYhGkSbhkcQvOMDqFJu24642R2j9pZeDWdr9SvqcBqOtsrRuiObhkGVPBM0Kn7JaNVqDugtq5vrO9jhOmQlm5Hx8D21CiQtQrkH7EQuGSb+NrGpjkWtauznJJ0BuY4JQlCpEsIOdQ3dnXW7n/rDLzrEqIw/IKTEjYp0SPGKB/rcg8VsLMwjY1MgjBFgbA4pSQmgM2A9yUIUU5JdrMY+F6RPx6jaWKCtBADPvhAgVZEa5mcS4o2E2gP1HwYd1K29nIaL+e/o92j3HhoLZOjAlUdN3YPnjxPUJrmm7HSbxcelbjlWx/JGLLg/dDH+GBiY/egqiMc6Zgva8vrmYXUyvzi0oePqQ6ZX1xaSK0sr2fyZY3+g5MGVupYqF3uFY93CtXtwmGH7BSqe8XjQu2yUseTBt4AysHcMrZrdkIAAAAASUVORK5CYII=" nextheight="708" nextwidth="1716" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">The compare function returns Greater, Equal, or Less when given two orders </figcaption></figure><p>It might not look like it <span data-name="loudly_crying_face" class="emoji" data-type="emoji">😭</span>&nbsp;— as I said, Rust is pretty wonky. But In Rust, this function returns an <code>Ordering</code> which is <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://doc.rust-lang.org/std/cmp/enum.Ordering.html">like a shorthand for <em>either</em></a> <code>Greater</code>, <code>Equal</code>, or <code>Less</code>.</p><p>So <em>if</em> <code>a.sim_value.mev_gas_price</code> &gt; <code>b.sim_value.mev_gas_price</code> <em>then</em> the function will return <code>Greater</code> . It’s probably <em>approximately</em> clear that we’re comparing gas prices of two different orders, but let’s just double check here.</p><p>The <code>cmp()</code> function takes in two variables, <code>a</code> and <code>b</code> of type <code>SimulatedOrder</code>. We find <code>SimulatedOrder</code> in <code>primitives/mod.rs</code> , which is intuitive: these are the “primitive” types used throughout the codebase. </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/a39be86b459e1f84567fa4aaa468d2bc.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAUCAIAAABj86gYAAAACXBIWXMAAAsTAAALEwEAmpwYAAADLklEQVR4nK1UzUsbQRR/m2Sz2ygKId+7m1V3zSYbE5NsEr+ptfTQS4tHT0J7E2pbj0IPYrW3FpoI9mSr4Kn+BV5KKR48iUdB0VQQ01KMBwlo3DIzmzXRFrQVfjx+M/t2fm/ex8BBWS+e6j/P9R9l/df5raGko2MPyjoUT/Wvm7tv3n54lZ97NpMbn3r//3gxnX85M/dlc7d4qsNBWc8trHjdrYwigUMEqwj2INBV2DFMTl/59DdA4N3C52JZh/3j89n5ZXAq4E1YhBRwCYpPUnwCkwSFLXAJ4DrRDpe08EngOmlRA38cXAq4wpfhDoM3DE55dn55//gcCqXKdG4RXArdlgE+Af44LabBH7cgmSTFoxNtgoY0+DhwCcItQoqAFjWrkAKPCu4IeCPgjWIZBZqk6dxioVSBvaMzJOAOMy1ZWkwzUhfwKeCSKEBvFPwxRHwxxH2xC3gj6JNPxT5VTx929qimwN7RmSFgDWTswR4m2G2T+ml50BYaskl96BRnuwGXUiUhcIaMJUoR2Q/VeV4VgCaJFXsZaYBVhprUB43h+80dDykhc/HDTVEnkF9CcXlU8OA8EOtScVwKjktBDuYlaiO9lgAqcsjIMqpVtFq0aDXjUczVi6U/jhxuIOBsN3qRFIrUlpzijRhixCJE8EXVmwi4Iw1yDytlWSnrkLutoka3ZBipi4xCzSViRhCkf3yq0ZTXSRHFJ9AQBTpo3OBkAmgxbRXQWBiHcmhQwB+z8BrFdaKrXPcGng4qoIEvBVwahC7wxauTqdSMaw131+xcqjyxVwRi9mCWae1m5QEmdNch94Evgoc+asAsABEgXWBumsSj4l5QoVm+lCLFJmh0SxclaJSgNci9jNwHfpLuepgd5a8pTG2/ke5olqdyn5BAoUTmQHFI/XZ54I4yyIbusXI/LQ+AkMHt/6fnzMhPLalfOtun80uF0hnslSozuUX0/LIisC3Q2AYObNEyiG097BhXublDiCXwOvfxe0lHAiur6yNjk8NPJh6PPn80Om7af8bw04mRscmV1fW9UgX2j/Wt4snG9uHa5s63ja1bwdrmzsb24VbxZP9Y/w3BFg2ElG9zewAAAABJRU5ErkJggg==" nextheight="1302" nextwidth="2048" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">The values being compared are large integers</figcaption></figure><p>Okay phew! We can now see that when we compare <code>a.sim_value.mev_gas_price</code> to <code>b.sim_value.mev_gas_price</code> , we are comparing two very large integers and that the function <code>cmp()</code> tells us whether the value for <code>a</code> is <code>Greater</code> than, <code>Less</code> than, or <code>Equal</code> to the value for <code>b</code>.</p><p>WOW! If you’ve made it this far without knowing Rust, great job. At this point, you can see if we configure rbuilder to sort by <code>OrderMevGasPricePriority</code> , then, when the block builder calls <code>pop_order()</code>, it will first pop orders that have the greatest <code>mev_gas_price</code> and process those first. That means that orders will be ordered within the block by <code>mev_gas_price</code> — exactly what we expect.</p><p>Therefore, the last thing we need to check is how the configuration is set. If we can verify that the config file in-use (i.e., by checking that the TEE attestation covers the config file (suffixed <code>.toml</code>, see <code>rbuilder/config-live-example.toml</code> for an example) has what we expect, then the block builder will sort orders by priority fee. One last go… </p><figure float="none" width="428px" data-type="figure" class="img-center" style="max-width: 428px;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/65b0f1099b7b37c4abf1230ff49bb242.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAATCAIAAAB+9pigAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD2ElEQVR4nKWVfUgbdxjHHxNPi2aGhcSXmhdr3i5m0WoSE42OSYUN+4ZQqJTYtXajLf1jsLJAoR1rYTDYWJH9PUMZbP9M2f6ypS0tUVywNSTB2NTE8+5iFhMvZy5q0Mb0xiW2q4NS4+Dzx/N7ue/3+T3P8ftBIssmsmxs8w0y/4PNfykoQ0F9OcNG1lmCYQkmh6f2D8HkCIaTWs6bcQZctMGSaW6QeslSWTZeOMRG0Sxn2MQmS7/kpMh0fnKThViGS5xMs7/e/euLH37+8vs7jm9Hrn83cmPYef3HkWJwfj3s/OanX24M3/ntrjtfDC5RiKyzoZWtpTTb03/BUCk71qmp71XzPlAC1AHvIECR8KUAgt5TnxOp7dDKi+g6C2SaDcbWnsfSPQOXNXX6j7pMsl4jYmoFIQo1OqhuKo5aAxxQHBm4PBddDcbWyDQLeGp7llz1YvGu/iHgy0CkB4EWhDpOXZz/pkYHEhQkOhCjHJL8UIzu0n29WmsARP7hqc9mQrFZcpVgcrBAZ70Y9eRZxHr8LIjU5Q3mMqVZoO6oVFmRRnOJzFihspbKjAJVZ4nMiChMZcp2pMEM9Yf5CiOSp0rTKVB38mRtPFlbldYGFY0dJ8+5A7gPpxbpHGDJrCccd/sx69FBQOT5RLQcIvVOIN7N2+Z3QAGRd5z4dNIX9mLUAp3dMZjyLxj77KVidbupW65p1zZZtE2WmkOt7ytaQKjeg+4rqpsAkVuPn53whjzhOJZ8w8B8bBBEqjJpM4hRRHq48pD5PaWFL20rkbaW1LfyZCYQ67haC1V7M5j/jwFm/ORMmbJd091/sO1jpe0EorQIVe162xExakWtPdJmm7TZVqvvqEYt+zmBO7Bo6rNDjV6gtfEURiHaDXXNINFWqYylUoNYay5XtFQ0tpYrWvhSA4jeYbCrB4W/aDpA2E6eA3491yWR+lUdUBBpOITqneB1J99GjR7KFF39Q1N+zItRi3QWFumcD6c9oZi1zw4gAYESKhr2w4E8gkYAie3o4JPgkp+g8dQ2EExuLpr2hJZvO0cvOG6dv3rTfuXamUuOgYuOgYtf7RnH6UsO+5Vr56/eHHLcuu0cnQnF5mJrBMPCUpoNrbzw4dTTUHTCOz8+OfPn/amxe66xcdfv44/3yNj449F7rj/uT41Pzkx4558Goz6cClNbkXUW/t7grr1QIuPDKXeAdHnDjzzBh9NzD6YDRfFweu6RJ+jyhd0B0o8n5xMZgsnFNvLXdeGpwZJbz+KZQJSZJVf9BM2BJ3049U78eLKwf5akA1FmPpEJU1sEk4usc+/BP3+qdeXcpZdQAAAAAElFTkSuQmCC" nextheight="612" nextwidth="1058" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">Required configuration setting to use OrderMevGasPricePriority</figcaption></figure><p>In Rust, we use a library called <code>serde</code> (short for “serialize - deserialize”) to parse string arguments into the strict types that Rust needs in the program. </p><figure float="none" width="596px" data-type="figure" class="img-center" style="max-width: 596px;"><img src="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/7b077a221380ca9553c24341e110d142.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAOCAIAAADBvonlAAAACXBIWXMAAAsTAAALEwEAmpwYAAACxUlEQVR4nK3T20/SURwA8O8PEQHNCyuu0s8hvyWE8AN+3sV5BSHNal6aTdu6rMtbD+X0qYceWq/1H7TesgdfmnO++BAla5pLZKEkAwQF3CByINlpB1F76GLa9tnZ95yd8/2e8/vuB6EUWksifwL54tjq/+CL44RrSRRKIQgm0dpXFE4jHMTR+le0vnUsG0m0+R1F0zjtRhpBIIG8MfTo2Ysbdx8Mj4713BnpuXb//PWju3BzxHb13sOnzwMJ5Esg8MZ2nMEvHbYhvVgqbKLghBRAAiD9iWRvlPx+MROwpFiuHKC4xjzgiaa8sR3wRNNzy6Ha7mHgK0FsIORGolQPpTRRqseBVJcJ6AwcgESLRxmesnb3yGj27imhGhOrga+oPjf80RtdjqTAHd5+t+Qzdg4CvwwfltEg1oLoLEi0mEgF4soDEu3eqAWpDmS40sH6yTOYUA1ckrZcfv8p4A7jAin74mema4jDtPCZFh7TKmi05TOtBFVTwLQRVF1xg5WtNvEMrXl0Mw+v1xJUHUdjYqsaCaqWrTblakyEspqjaeLpmtmqRl5lM8hp2tzvcPndG8lsgaquoUJt+ymDRcRYC6usJfXd+bo2gjQCaeQb2nLVmXTlVfj5+JoV2cv+WgVwSYNlwOHyZQu8XVw1dl6BEo1AbRMZeou0F7kVVrayCe8WUFCkhCIKE1B/zPvXAlySRVazyuvylA1cZX0OyeTIDbh14sps9/DFD0GkggKFwTK4/4m2HS4/Y+6HHDnuM+c0cEmMXwZ8BcYt+zcFCgAh3XJpbjmEm7yymf7gidwee0Kb+xjLgN7cp+vY096L7U8PYTeJztJ/a/Txwmp4ZfMb+OPIGYjPLvmm7AsT02/GJ2devZ55eVTjkzMT0/Yp+4LD5XcG4v44guAWwj9zIDHviThcgVmX/5gc7uC8J+IMJLyxneAW+gFqrjp8iavI3gAAAABJRU5ErkJggg==" nextheight="670" nextwidth="1548" class="image-node embed"><figcaption htmlattributes="[object Object]" class="hide-figcaption"></figcaption></figure><p>This is really, really confusing (I warned you…), but the <code>#[</code> blocks are like auto-transforms. What these say in natural language is something like “take a text input in kebab-case (i.e., the "mev-gas-price" in our <code>config.toml</code> file) and deserialize (parse) it into CamelCase (e.g., “CapsLookLikeACamelWhichIsRustStandardConvention”). If the text input ends up matching “MevGasPrice” then our <code>Sorting</code> setting will be MevGasPrice.</p><p>If we go to the <code>ordering_builder</code> , we see how the builder is initialized: </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/d037003c43e7ae238472f4f7ba4b5f79.png" blurdataurl="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAWCAIAAAAuOwkTAAAACXBIWXMAAAsTAAALEwEAmpwYAAADvklEQVR4nK1VXW/TZhQ++TI0wWraZk6aNLYTf6ROPQqsuHa+2k4T06btYr+IwtWmAeJqtOJiaJeTGLvYEFWYVrFUoE64H7AhNZRWrVhZSatoUqugkHk6r502ZSsr66RH1pvzHp/H7znP8wZ+r1lr21alYW3+aT2v/z+o1LHg2ra1XrdgbdtarjaK5sLXP5o3frj/zaR5SNy4Y357xyyaC8vVxtq2Bb9tWT8/ea5pH+QyilvvA1oEWjgU2kVw93Spww9WNlf/sGC52pg0y11KFoIcRFIQlDEjKLcsxObPlq2d+J5kEXOCMvj5gGyUHi4tVV/C0mZ94u78sVQWKB5CCjBp6ExBqBcYhSwUXO9gZ4tJQyjVzLEjBHZaUA5Ixu17vyxWarBYqd0szdKyAe0ChNP4Jj4V6JR2wTQL2UUxR4Vwn7Nm0tgZP++ATgL0HBW04t358voLJPi+ZHYpBQgf97GaJzYA3GngBoHVIPqOg0g/EtDJ/VufbIEA7vhRQZuYaiHoUArwVr8vrrtZzSfmXYlcQDlDyUPA6RAdgO5TTYKD4G8EN0uzAUmHLtXNG1iO1fCTYxrEToOfA4oFinPO/t8IyAmyWKJd2is4aZ9uvNKWV+ICeNk2cbCVYAaHTCdxXBG1OcY0hGQyQ/snGakdCdu7vURL5GnDlhBZBCTjVivBMVnHEzBpom6CzpQjoRAxBy2Qtby7a4uq3c4kOTYBOcGeFn1XMhn1XU9U87Ia8FlIZLzSkFcsuIU8JY/4hIJHGnEJBVcyR8kjbcoZiJ3EcvYnIxMpbVuvU/rHGczQkgEdaeB0FzdISUM+Me+Whj1ETpSYh0QGIseB6UPfRfsdozAKRN522mXbE32Q2IdANiB8AthBYFQUT/cpYHUiJA11FR3AOwCvKZEMU9y1Vau//kWmHX1H4ronnoFE3iUMAdPvEokPxGHgMgg+B5yBvuN0oBNvJNOZgGQAxCCmHVE/9sjvU+mPXNJ7gROfoKX9nPPm7me+pvq+JyAE3Scp5UNI5iGRIx1XoYPoxL4s39RoO3fRrak5bJGfxzEk8jgDPot+DgpIEFFxmKHeA5sZCfyiVrw3X67UYGnz5e3pX/EE9n3g7gFvHLzkSfEYpDgSIRfGQeDnAaJtkj5pLjzeqOMfzv3ys2vXi59+ce385avnLo6PXho/d3H87OdXEBfGRgnOXhhzIq/F6KWx85evfnblqy+vT5iPny1XG/B0yyqvv3i4sjH9aHVqbvGn2fIhMTW3OP1o9cHKRnm99nTL+gtB2WF9OfizDAAAAABJRU5ErkJggg==" nextheight="1192" nextwidth="1700" class="image-node embed"><figcaption htmlattributes="[object Object]" class="">Initialization of builder pulls from the config</figcaption></figure><p>Whew. As a final review, here’s what we know happens in the code:</p><ul><li><p>The builder builds blocks based on an <code>OrderPriorityType</code></p></li><li><p>If the <code>OrderPriorityType</code> is set to <code>OrderMevGasPricePriority</code>, then when we <code>pop()</code> orders off the stack, we will first pop orders with the greatest <code>mev_gas_price</code></p></li><li><p>We set the builder to use <code>OrderMevGasPricePriority</code> by passing the argument <code>sorting = "mev-gas-price"</code> into our <code>config.toml</code> file.</p></li></ul><p>Therefore, what we need to verify from the TEE attestation is that:</p><ul><li><p>The BuilderNet TEE is running the same rbuilder code that we’ve reviewed here.</p></li></ul><ul><li><p>The builder running in the TEE used a <code>config.toml</code> file that has the <code>sorting = "mev-gas-price"</code> line.</p></li></ul><p>If we can verify all of that, then we <strong><em>know</em></strong> that transactions on BuilderNet <strong><em>will be</em></strong> sorted in priority order.</p><h3 id="h-verifiability-as-a-central-good-of-decentralization" class="text-2xl font-header">Verifiability as a central good of decentralization</h3><p>I’ve claimed before that decentralization may not be important for its own sake; instead, it seems good&nbsp;<em>for other things.</em> In this article, I’ve shown how TEEs introduce verifiability: by producing an attestation that can be locally verified against source code which any user can verify. I’ve also shown how users can take the next step and <em>actually verify</em> the behavior of the source code.</p><p>While much of this discussion is still somewhat theoretical — for example, I’m not currently aware if or where BeaverBuild publish TEE attestations to the code they’re running — I hope you can see the future design space for TEEs and a plausible pathway to get there. BuilderNet makes many more promises aside from transaction ordering — refund mechanisms, privacy guarantees are two examples — so being able to verify these guarantees will be essential to its success.</p><p><em>Verifiable</em> systems are important for fair, transparent, immutable, and censorship financial markets, and I’m more optimistic than ever that Ethereum DeFi is on the way to achieving that goal.</p><p><em>Thanks to Dan Marzec for providing feedback on parts of this article. These are my independent thoughts and do not necessarily represent the views of my employer.</em></p>]]></content:encoded>
            <author>mud2monarch@newsletter.paragraph.com (Gyges Lydias)</author>
            <enclosure url="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/6a67407d41d1fb961708caada77a453b.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Believe in Something Real]]></title>
            <link>https://paragraph.com/@mud2monarch/believe-in-something-real</link>
            <guid>TWibUzYfjv4j4evArMT0</guid>
            <pubDate>Wed, 26 Feb 2025 14:59:41 GMT</pubDate>
            <description><![CDATA[TradFi and regulators are excited about crypto, but industry sentiment is terrible. Why? ]]></description>
            <content:encoded><![CDATA[<p><em>These are my independent thoughts and do not necessarily represent the views of my employer. Cover art: "The Monk by the Sea" by Caspar David Friedrich, 1808-1810.</em></p><p>A malaise pervades the crypto industry today. On one hand, the regulatory environment has never looked better, and TradFi interest in public blockchains is at an all-time high. Yet internally, crypto feels more <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/miaferrariii/status/1895863245027885361">stagnant</a>, circular, and cynical than ever. How can that be?</p><p>I think it's because crypto today only exists to serve cryptoassets. While the total market cap of crypto nears $3t, very little of that value is exogenous to our industry. The tokenized traditional assets that have come onchain (dollars, t-bills) have been tokenized primarily to serve <em>crypto's</em> needs, not the imperatives of the assets. Crypto has not improved the traditional financial system; yet.</p><p>It's true this is partly because crypto hasn't been <em>allowed</em> to change the financial system. The Biden Administration seemed to do everything in its power to prevent adoption of the public blockchain innovation that exploded in 2020 and 2021. It <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.wsj.com/finance/currencies/crypto-banks-relationship-trump-administration-414ff706">debanked</a> crypto entrepreneurs and companies. It <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.federalreserve.gov/newsevents/pressreleases/bcreg20230103a.htm">froze</a> all bank experiments with the technology. It investigated or sued the best actors in the space, turning <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blog.kraken.com/news/sec-kraken-dismiss"><u>earnest engagement into prolonged litigation</u></a>.</p><p>It's also true crypto has obvious innovations that <em>could</em> improve traditional financial services. Automated market making is an elegant way to improve liquidity for low-volume assets. Collateralized lending extends credit to people with just one dollar of net worth, exactly the people most likely to pay the highest interest rates. Even perps make markets more efficient by making option durations infinitely granular.</p><p>But it's also true that crypto hasn’t succeeded, for whatever reason. In fact, these days, it's more common to see crypto fail. Parts of our industry not only tolerate but actually <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/smyyguy/status/1881137983136620751"><em><u>celebrate</u></em></a> and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/blknoiz06/status/1750019729287242193"><em><u>justify</u></em></a> modern memecoins when they are plainly <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/zackvoell/status/1890663733929677066"><u>extractive</u></a>, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.coindesk.com/business/2025/02/17/javier-milei-memecoin-creator-also-launched-melania-admits-to-sniping-tokens">circular</a>, and <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/lakejynch/status/1890352598835724382">shortsighted</a>. Projects race to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/movementfdn/status/1861107961286009042"><u>"TGE" (Token Generation Event) pre-product</u></a>, intending only to cash out, which leaves roadmaps half-completed and vaulted promises unfulfilled. Others see government endorsement as an <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/zackvoell/status/1889294274690224540"><u>explicit product strategy</u></a>, which depletes the common stock of credibility we all share.</p><p>What is needed is real innovation. A crypto product you don't need to <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/jessepollak/status/1891878465944625265"><u>pay people to use</u></a>. Examples, not explanations. A proof of concept -- yes, a proof! -- not another promise. Justly or not, we must now produce a tangible example of change to break through this malaise.</p><p>I think this is <u>required</u>.</p><p>I'm also telling you it will come. Not from blind faith, not from naive optimism. But from conviction. It will come because of the work, creativity, and Spirit of a few people -- who dare to change the world.</p><p>We believe in something real.<br></p>]]></content:encoded>
            <author>mud2monarch@newsletter.paragraph.com (Gyges Lydias)</author>
            <enclosure url="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/cdc680ff97e19d4ddf75598f808faa72.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Disaggregating Decentralization]]></title>
            <link>https://paragraph.com/@mud2monarch/disaggregating-decentralization</link>
            <guid>jDgwWR7FxQCXTz05ulsO</guid>
            <pubDate>Sun, 26 Jan 2025 15:11:26 GMT</pubDate>
            <description><![CDATA[“Decentralization” is an ubiquitous word crypto, but I find it to be confused. Decentralization seems mostly good for other things -- I explain what those are.]]></description>
            <content:encoded><![CDATA[<p>“Decentralization” is an ubiquitous word in the discussion, marketing, and governance of crypto, but I find it to be confusing — and confused. Sometimes people tout decentralization as a primary benefit when they seem to care about a different characteristic instead. I’m not sure decentralization is important for its own sake; instead, it seems good <em>for other things</em>. I think we should speak simply about those other things, rather than using “decentralization” as a catch-all.</p><p>In this blog post, I identify <em>those</em> <em>other things</em>. We can speak more precisely about the nature and benefits of decentralized systems, whether they be smart contract protocols, blockchain networks, or anything else. Many of these characteristics are the primary advantages of the new financial system being built on public blockchains — a system perhaps misnomered “DeFi.”</p><p><em>These are my independent thoughts and do not necessarily represent the views of my employer.</em></p><div class="relative header-and-anchor"><h2 id="h-the-other-things">The Other Things</h2></div><p><strong>Fairness. </strong>Sometimes, people mean that decentralized systems are fair. Fair systems preserve no privileged positions. Satoshi has the same rights within the Bitcoin network as you or I. Fairness is good because it sets everyone equal, empowering everyone with maximum agency.</p><p>In a regulatory context, the extent to which someone has a privileged position in a system is essential to evaluating their <strong>“control.”</strong> If someone has control, it may be reasonable to give them regulatory obligations; but if everyone is equal, singling out a single actor may be arbitrary.</p><p><strong>Information symmetry. </strong>Relatedly, people sometimes mean that decentralized systems naturally provide symmetric information to everyone. The <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.sec.gov/newsroom/speeches-statements/speech-hinman-061418#:~:text=The%20same%20reasoning%20applies%20to%20digital%20assets."><u>Hinman Speech</u></a> explains that the centrality of an issuer or promoter to the success of an enterprise implies disclosure obligations. However, the cause of the obligation is that the central party has asymmetric information that is likely of material importance to investors. It’s information asymmetry that is most relevant, not decentralization purely.</p><p><strong>Openness.</strong> Sometimes, people mean that decentralized systems are open. Everyone can run a Bitcoin node, compete in the proof of work competition, and broadcast transactions. There are no gatekeepers.</p><p>Open systems are more accessible to more people. Lower barriers to entry also facilitate innovation, increasing the pace and possibility of user-beneficial improvement.</p><p><strong>Verifiability. </strong>Sometimes, people mean that decentralized systems are easily verifiable. When decentralized systems allow anyone to participate in the network, every user can verify the results of a transaction for himself. This increases the trustworthiness of the system.</p><p>Relatedly, decentralized systems are often <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://etherscan.io/token/0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2#code"><u>verifiably open source</u></a>, which means users can know exactly what will happen when they use a program. This enables better risk management and safer, community-reviewed software. <strong>“Transparent”</strong> could be a synonym for “verifiable.”</p><p><strong>Resilience. </strong>Sometimes, people mean that a decentralized system is more resilient because it does not require a specific actor to function. If one actor fails, another can take its place. For example, the Bitcoin network continues while just two node operators run the software. Or, users can continue to use the system without the failed actor: users of many Ethereum L2s can withdraw funds and effect transactions on the L2 without having to rely on the sequencer. When there is no single point of failure, systems have higher uptime.</p><p><strong>Lack of intermediation. </strong>Traditionally, people mean that decentralized systems lack intermediaries. Such systems can decrease costs, trust requirements, and time delays when compared to traditional systems. Many decentralized systems, like Ethereum or Aave, enable complex transactions that are still peer-to-peer.</p><p><strong>Immutability. </strong>Decentralized systems must also be immutable, because if no one has a privileged position then no one can upgrade the protocol without everyone else’s concurrent adoption. This kind of software is more reliable for users, who can trust that the rules of the game won’t change on them.</p><p><strong>Censorship resistant. </strong>Perhaps the most important derivative of decentralization is censorship-resistance, which is the ability to execute a transaction in adverse conditions. Because Bitcoin has abundant and diverse node operators, it’s easy to execute a transaction in the face of censorship by finding a few friendly node operators to submit your transaction. This is important for maximizing human freedom.</p><div class="relative header-and-anchor"><h2 id="h-whats-necessary-for-decentralization-and-when-is-decentralization-necessary">What's necessary for decentralization - and when is decentralization necessary?</h2></div><p>Decentralization is a spectrum. It’s probably the case that all of The Other Things are necessary for something to be ‘truly’ decentralized, but nothing is sufficient alone.</p><p>But who cares? Decentralization is not good for its own sake — it’s good for The Other Things. If a system has intermediaries, <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/geniusyinka/status/1840445516917690719"><u>such as an intent-based bridge</u></a>, it may not be purely “decentralized.” But it’s still good for users if it’s fast, cheap, and resilient. Or, if a blockchain has a <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://docs.arbitrum.foundation/state-of-progressive-decentralization#2-validator-ownership"><u>permissioned validator set</u></a> (i.e., it is not maximally “open”), it is still safe if users can re-execute transactions with their own full node (i.e., it is “verifiable”) or <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://x.com/donnoh_eth/status/1879210463952818472"><u>overcome L2 censorship</u></a> with an L1 contract call (i.e., it is “censorship resistant”).</p><p>It’s also the case that many projects claim to be decentralized when they really aren’t. The full assessment of a project’s technical decentralization is complex and intensive, but it may not even be necessary. Focusing on the specific benefits provided by decentralization, like immutability, verifiability, fairness, openness, and censorship-resistance is a more consumable exercise, and I think it’s more helpful for users. We should focus on whether systems provide users with those benefits rather than whether systems meet some Platonic ideal of “true decentralization.”</p><p><em>These are my independent thoughts and do not necessarily represent the views of my employer</em>.<em> Thank you to some friends who provided comments.</em></p>]]></content:encoded>
            <author>mud2monarch@newsletter.paragraph.com (Gyges Lydias)</author>
            <enclosure url="https://img.paragraph.com/cdn-cgi/image/format=auto/https://storage.googleapis.com/papyrus_images/dbb0009fba5f3a0277810020fa25657b.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>