<?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>chengmarc.eth</title>
        <link>https://paragraph.com/@chengmarc</link>
        <description>DeFi mechanisms, protocol risk, market structure | On-chain since 2017 | Mathematics @UofT '23 🇨🇦</description>
        <lastBuildDate>Wed, 14 Oct 2026 00:16:09 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>chengmarc.eth</title>
            <url>https://storage.googleapis.com/papyrus_images/ce60033e8c6676b683432a32d43dd19e7216652207fcf585e1076071abccd746.jpg</url>
            <link>https://paragraph.com/@chengmarc</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Extend, Never Correct: From SSTORE to RISC-V, the Backward Compatibility Constraint Governing EVM Evolution]]></title>
            <link>https://paragraph.com/@chengmarc/extend-never-correct</link>
            <guid>DAXC0l2xx2VlGj2mEWQP</guid>
            <pubDate>Sat, 16 May 2026 13:14:26 GMT</pubDate>
            <description><![CDATA[Every contract ever deployed on Ethereum is still there — executing under rules written in 2015, some of which turned out to be wrong. The EVM was built to be permanent. That permanence is also its prison. Four opcodes show what changing it actually costs: replay attacks patched years apart, a security fix that nearly shipped a new vulnerability, a cleanup tool weaponized by design. Then EOF pulled from Fusaka. Now a proposal to replace the EVM entirely with RISC-V — while keeping every legacy c]]></description>
            <content:encoded><![CDATA[<h2 id="h-1-more-than-just-a-meme-coin" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">1. More Than Just a Meme Coin</h2><p>Somewhere on the Ethereum blockchain, there is a contract I deployed. It does nothing useful. Tokens were minted, nothing of consequence happened, and I have not thought about it in years. But the bytecode is still there—sitting in the state, waiting to be executed by rules I did not fully understand when I wrote it. It will be there indefinitely, under those same rules, whether I like it or not.</p><p>At some point, almost everyone in this space has done something like this—written a contract, deployed something, just to see if they could. Pump.fun has made it easier. But there was a time when you had to write the Solidity yourself. I bought my first ETH in 2017. I have traded it, bridged it, lost some of it to gas fees I did not understand, and at some point deployed that meme coin just to see if I could. The contract worked. But the part that stuck with me was not that it worked—it was that I had no real idea <em>what</em> was executing it.</p><p>The thing about Ethereum is that most people who use it—trading, providing liquidity, deploying contracts—never have to think about what is actually executing their transactions. There is a machine underneath all of it. It has rules. Those rules were written in 2015, and some of them turned out to be wrong, or at least incomplete. Fixing them without breaking everything already on-chain turns out to be one of the more interesting engineering constraints in the space.</p><p>This piece is about that machine. Some of its rules have already been changed. Others cannot be—not really. The difference turns out to matter more than you might expect.</p><hr><h2 id="h-2-what-actually-executes-when-you-hit-send" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">2. What Actually Executes When You Hit Send</h2><p>Most people who interact with Ethereum have a mental model that looks something like this: you send a transaction, it gets picked up by validators, it lands in a block, and something happens. The "something happens" part is where most mental models stop.</p><p>That something is the EVM.</p><p>When Satoshi designed Bitcoin, the scripting language was deliberately limited—intentionally not Turing complete. You could express "send X bitcoin to Y address if Z condition is met." You could not express much else. Ethereum's founding insight was that the interesting design space lived in that "much else"—arbitrary computation, not just payment logic.</p><p>The EVM is what makes that possible. It is the runtime environment that every Ethereum node runs identically—opcode by opcode, every node producing the same output. The blockchain records the outcome. The EVM is what produces it.</p><p>Wait. If the EVM produces the outcome, but the blockchain only records it—where does the EVM actually live?</p><p>Not on-chain. The rules of the EVM—which opcodes exist, what they cost, what they do—are encoded in every node's software. Nobody owns it. Nobody controls it. And yet, somehow, thousands of independent machines all run the same rules.</p><p>So what stops anyone from just... changing theirs?</p><hr><h2 id="h-3-you-can-cheat-nobody-cares" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">3. You Can Cheat. Nobody Cares.</h2><p>A natural thought at this point: if the EVM runs locally on every node, what stops me from modifying mine to produce a different result?</p><p>Nothing, technically. You can fork the client software, change whatever you want, and run your modified version. Your node will execute transactions under your custom rules and arrive at different outputs.</p><p>The network will then ignore you.</p><p>Every other node is running the standard rules. When your modified node produces a result that diverges from theirs, the rest of the network rejects it as invalid. Your transactions do not get included in any block that the network accepts. Your modified chain forks off into isolation, a parallel ledger that no one else recognizes or builds on.</p><p>That is consensus. The word you always heard about.</p><p>The corollary is the one that matters for this piece: changing the EVM rules legitimately requires the entire network to upgrade simultaneously. Not because anyone can force nodes to upgrade, but because a rule change that only some nodes adopt splits the network. The upgrade is all-or-nothing.</p><p>But here is the harder question. If someone's money gets stolen—not a bug in their contract, but a fundamental exploit—can the network revert it? Most people assume the answer is obviously no. Ethereum is immutable. Code is law. The whole point of a trustless system is that no one gets to make exceptions.</p><p>Except once.</p><hr><h2 id="h-4-when-the-chain-splits-and-doesnt-come-back" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">4. When the Chain Splits and Doesn't Come Back</h2><p>Ethereum has gone through nearly twenty hard forks since 2015. Most people have never noticed.</p><p>That is because most forks are planned upgrades with broad consensus. The community agrees, node operators upgrade, the old chain dies quietly because no one stays on it. No drama, no split. Just a software update that the entire network coordinates around.</p><p>Then there is The DAO.</p><p>In 2016, a smart contract called The DAO was exploited for roughly 3.6 million ETH. [1] The Ethereum community faced a choice: accept the loss as immutable history, or intervene. The majority voted to intervene. What followed was what developers drily called an "irregular state change"—the hard fork did not technically reverse transactions, but directly rewrote Ethereum's ledger to move the funds out of the attacker's child DAO contract and into a recovery contract, allowing original investors to withdraw. [2] The funds were returned.</p><p>But not everyone agreed. A portion of the community—roughly 10% by mining power at the time [1]—believed that rolling back the chain violated the core principle of blockchain immutability. Code is law. The hack was valid. They refused to upgrade.</p><p>The result: two chains, both alive, both carrying the full transaction history up to block 1,920,000 [1], then diverging permanently. Ethereum (ETH) on the new chain. Ethereum Classic (ETC) on the original. Both still exist today.</p><hr><h2 id="h-5-sign-once-collect-twice" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">5. Sign Once, Collect Twice</h2><p>The DAO fork left two chains running the same EVM, the same transaction format, the same signature scheme—and every wallet mirrored across both, same address, same keys, same balance.</p><p>You are a hacker. The chain just split. Is there any way to profit from this?</p><p>Turns out, there is. Here is exactly what you do:</p><ul><li><p>You sell someone 5 ETH worth of goods. They sign a transaction: send 5 ETH to your address. It confirms on Ethereum.</p></li><li><p>Take that signed transaction, byte for byte, and broadcast it to the Ethereum Classic network.</p></li><li><p>The ETC nodes validate it. Same signature scheme, same format, same everything. It goes through.</p></li><li><p>They signed once. They authorized one transaction. The network validated two. The buyer just sent you 5 ETC they never intended to spend.</p></li></ul><p>Whoo hoo! Free money.</p><p>The attack surface was never in any opcode. It was in an assumption baked silently into Ethereum's design: that there would only ever be one chain. No one wrote that assumption down. No one enforced it. It was just true—until the day it wasn't.</p><p>The transaction-layer fix came first, and it came fast. EIP-155, included in the Spurious Dragon upgrade four months after the fork (November 2016), embedded the chain ID directly into the transaction signature. [3] A transaction signed for Ethereum now encodes chain 1; one signed for Ethereum Classic encodes chain 61. The signatures are cryptographically distinct. Replaying one on the other fails validation. The replay attack, as described above, was closed.</p><p>But closing the signature hole left a second problem open. Smart contracts—executing inside the EVM—had no way to ask which chain they were on. A contract deployed identically on both ETH and ETC would execute identically on both. If a contract's logic depended on chain identity—verifying a signature that embeds a chain ID, for instance—it had no mechanism to inspect that at runtime.</p><p>EIP-1344, included in the Istanbul upgrade (2019), added <code>CHAINID</code> [4]—a single opcode that pushes the current chain's numeric identifier onto the stack. Ethereum is chain 1. Ethereum Classic is chain 61. Contracts could now condition their behavior on which chain was actually executing them.</p><p>The transaction layer was patched in months. The execution layer took three more years. One broken assumption. Two separate fixes. Different layers of the same stack, addressed on different timelines.</p><p>Woah, slow down. What exactly is an opcode? And what is this EIP thing we just talked about?</p><p>The answers will be introduced across the next three sections. Section 6 covers the machine itself—what the EVM actually is, and why it is built the way it is. Section 7 covers the origins: what is an opcode, and the initial opcode set that shipped with Ethereum in 2015. Section 8 covers the EIP—the only mechanism the network has for changing a machine that nobody owns. By the end of those three sections, both fixes will look less like patches and more like the only moves available.</p><hr><h2 id="h-6-a-stack-of-plates-determinism-over-performance" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">6. A Stack of Plates — Determinism Over Performance</h2><p>The Ethereum Virtual Machine is, at its core, a stack machine. To understand it, it helps to start somewhere familiar.</p><p>If you have taken an introductory CS course, you have encountered a stack before—it is one of the first data structures most curricula cover. Last in, first out. You push values onto the top, and you can only pop from the top. The plate stack analogy: the last plate you put down is the first one you pick up. Simple, constrained, and easy to reason about.</p><p>A stack <em>machine</em> is a computer that uses a stack as its primary workspace for computation. Instead of named registers (<code>a + b → c</code>), every operation pulls its inputs from the top of the stack and pushes its result back. To add two numbers, you push both onto the stack, then call ADD—which pops both, adds them, and pushes the result. No named variables, no hidden state. Just a sequence of push and pop operations.</p><p>A well-known example—Java Virtual Machine—works the same way. When Java compiles your code into bytecode, it produces a sequence of instructions that push values onto a stack, operate on them, and pop results off. This design was chosen for one reason: portability. The same bytecode runs identically on any machine that implements the JVM specification, whether it is running on Windows, Linux, or macOS.</p><p>The EVM made the same architectural choice, but for a different reason. Portability across operating systems matters for node software too—Ethereum clients run on Linux, macOS, and Windows. But that is not why the EVM uses a stack. The driving constraint is <em>determinism</em>—the guarantee that the same transaction, executed on ten thousand nodes across the world, produces exactly the same result every single time.</p><p>The second reason is economics. EVM bytecode lives on-chain. Every byte costs gas to deploy. Stack instructions do not need to name registers (<code>a</code>, <code>b</code>, <code>c</code>), so the instruction encoding is compact. <code>PUSH1 0x60</code> is two bytes. That is all.</p><p>Same architecture, different motivations: JVM optimizes for portability across operating systems; EVM optimizes for determinism across a global network of adversarial nodes. The distinction matters for what comes next.</p><hr><h2 id="h-7-the-day-they-switched-it-on" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">7. The Day They Switched It On</h2><p>On July 30, 2015, the Ethereum genesis block was mined. The network launched with what is now called the Frontier release: a minimal, intentionally rough set of opcodes sufficient to run the machine.</p><p>To appreciate what this meant, consider the contrast with Bitcoin. Bitcoin's scripting language is deliberately limited—not Turing complete by design. You can express conditions like "send X to Y if Z signature is provided," but you cannot write loops, you cannot maintain persistent state across transactions, and you cannot build programs that call other programs. This was a conscious choice: a smaller instruction set means a smaller attack surface.</p><p>Ethereum's founding bet was the opposite. The EVM is Turing complete—given enough gas, it can compute anything a conventional computer can. Loops, conditionals, recursive calls, arbitrary state. The <code>JUMP</code> and <code>JUMPI</code> opcodes alone are what push it over the Turing threshold: they allow execution to jump to arbitrary positions in the bytecode, enabling loops and branching logic that Bitcoin's script cannot express.</p><p>This power came with a tradeoff Bitcoin deliberately avoided: if you can write arbitrary programs, you can write programs with arbitrary bugs. And on a blockchain, those bugs are permanent.</p><p>The initial opcode set covered everything needed to make the EVM functional: [5]</p><ul><li><p><strong>Arithmetic</strong>: <code>ADD</code>, <code>MUL</code>, <code>SUB</code>, <code>DIV</code>, <code>MOD</code></p></li><li><p><strong>Comparison</strong>: <code>LT</code>, <code>GT</code>, <code>EQ</code>, <code>ISZERO</code></p></li><li><p><strong>Stack manipulation</strong>: <code>PUSH1</code>–<code>PUSH32</code>, <code>POP</code>, <code>DUP1</code>–<code>DUP16</code>, <code>SWAP1</code>–<code>SWAP16</code></p></li><li><p><strong>Control flow</strong>: <code>JUMP</code>, <code>JUMPI</code>, <code>STOP</code></p></li><li><p><strong>State</strong>: <code>SSTORE</code>, <code>SLOAD</code>, <code>MSTORE</code>, <code>MLOAD</code></p></li><li><p><strong>External calls</strong>: <code>CALL</code>, <code>CALLCODE</code>, <code>CREATE</code></p></li><li><p><strong>Self-destruction</strong>: <code>SUICIDE</code> (later renamed <code>SELFDESTRUCT</code>)</p></li></ul><p>The machine worked. Contracts could be written, deployed, and executed. Ether could move. Logic could run.</p><p>What the designers did not fully anticipate was that every decision made in July 2015 would be permanent—permanent in the sense that millions of contracts would be deployed depending on the exact behavior of these opcodes. Changing them later would not be a patch. It would be a betrayal.</p><p>They had built a machine. They had also built a constraint.</p><hr><h2 id="h-8-the-eip-change-a-machine-that-no-one-owns" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">8. The EIP — Change a Machine That No One Owns</h2><p>At this point, you have a reasonable question. You understand what an opcode is—an instruction that operates on the stack of plates. You know the initial set shipped in 2015. If those rules are encoded in every node's software, and not locked inside any contract on-chain, then changing them is at least <em>possible</em>. What stops anyone from proposing a new opcode—or modifying an existing one—to change how the EVM behaves?</p><p>Anyone can write a proposal. Getting it accepted is another matter entirely.</p><p>When a flaw is found in the EVM—a security vulnerability, an inefficiency, an assumption that broke under new conditions—there is exactly one mechanism to address it: an Ethereum Improvement Proposal.</p><p>An EIP is a formal specification document. It must define the exact behavior of the change, the gas cost implications, the security analysis, and the backward compatibility impact. It must be implemented by every major Ethereum client: Geth, Reth, Nethermind, Besu. It must be reviewed by core developers, discussed in public forums, and accepted into a hard fork—a network upgrade that all nodes must adopt simultaneously or be left behind.</p><p>This process is slow by design. A change to the EVM affects every contract ever deployed, every node currently running, and every developer writing code today. The bar for "this change is worth it" is correspondingly high.</p><p>But there is a harder constraint underneath the process. Even if an EIP is accepted, it cannot change the behavior of existing contracts. The bytecode already on-chain will be executed under the old rules forever. An EIP can change what <em>new</em> contracts can do. It can change the rules of the machine going forward. It cannot reach back.</p><p>This is the central tension of EVM evolution: the machine must improve, but it cannot forget.</p><p>But there is another way to read the EIP process. If the exit is open to anyone, it is also open to attackers.</p><hr><h2 id="h-9-sstore-a-safe-change-that-wasnt" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">9. <code>SSTORE</code> — A Safe Change That Wasn't</h2><p>You have read the EIP process. You understand the review criteria: the change must be beneficial, gas costs must be justified, backward compatibility must be preserved. The process is well-calibrated for deliberate attacks—an EIP that explicitly violates a core EVM invariant does not survive review. Explicit violations are catchable. What the process is not calibrated for is the interaction problem: a change that is individually correct, individually safe, but semantically dangerous when composed with assumptions already baked into deployed contracts. No single reviewer can hold the full state space of every existing contract in their head simultaneously. The attack surface, in this case, is not in any specification line—it is in the gap between what the EIP says and what the network has silently assumed.</p><p>January 15, 2019, one day before the Constantinople upgrade was scheduled to go live at block 7,080,000 [6], a smart contract auditing firm called ChainSecurity published a report that made this gap visible. [7]</p><p>EIP-1283 [8] reduced gas costs for certain <code>SSTORE</code> operations, specifically "dirty writes": cases where a storage slot is written more than once within the same transaction. The gas savings were real and the EIP had passed review. What the reviewers had not fully traced was the downstream effect on existing contracts.</p><p>Solidity developers had long treated <code>address.transfer()</code> and <code>address.send()</code> as reentrancy-safe. The reason was mechanical: both functions forwarded exactly 2,300 gas to the recipient—enough to log an event, not enough to execute a storage write. Reentrancy attacks require the recipient contract to call back into the sender and modify state. At 2,300 gas, that was infeasible. The safety guarantee was not in the code—it was in the gas cost of <code>SSTORE</code>.</p><p>EIP-1283 reduced that gas cost. Suddenly, 2,300 gas was enough. Contracts that had been written and audited as reentrancy-safe were no longer safe—not because their code changed, but because the cost of an operation they depended on changed beneath them.</p><p>ChainSecurity's follow-up analysis stated the broader lesson plainly: any change to EVM semantics inevitably propagates into the behavior of every deployed contract, and verifying that all existing contracts remain safe under a given change would require reasoning about every contract-specific property—a task that is infeasible in practice. [9]</p><p>The upgrade was delayed. When Constantinople eventually launched in February 2019, it shipped simultaneously with a second fork called St. Petersburg, whose sole purpose was to remove EIP-1283. The EIP was proposed, accepted, shipped, and reverted within a single upgrade cycle.</p><p>Nobody planted a bug. It was an honest oversight—a change that looked safe in isolation but was not safe in context. The EIP process caught it, barely, at the last possible moment.</p><p>This is the actual threat model. Not a trojan horse with a hidden payload, but the irreducible complexity of reasoning about a change that touches every contract ever deployed. The chain split showed how one broken assumption could propagate across two separate layers of the stack—requiring fixes years apart. <code>SSTORE</code> showed a different failure mode: a change that was individually safe but contextually dangerous. Here are two more.</p><hr><h2 id="h-10-selfdestruct-tnt-in-the-toolbar" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">10. <code>SELFDESTRUCT</code> — TNT in the Toolbar</h2><p>You are not trying to exploit anything. The previous version of you wanted to slip a backdoor past the review committee. This one just wants to see what happens—like a Minecrafter who found a bucket of TNT and has no particular agenda.</p><p>You come across <code>SELFDESTRUCT</code>.</p><p>You read the description: <em>destroys the contract, wipes its storage, forwards all Ether to a target address.</em> The original name, before they sanitized it, was <code>SUICIDE</code>.</p><p>Is there anything interesting you can do with this?</p><p>It turns out there is. <code>SELFDESTRUCT</code> can send Ether to <em>any</em> address, with no conditions. Normally, a contract with no <code>receive()</code> or <code>fallback()</code> function refuses incoming Ether. <code>SELFDESTRUCT</code> does not care. You deploy a contract, point it at your target, and fire. The Ether lands whether the target wants it or not.</p><p>A lot of contracts make assumptions about their own balance. Logic like: <em>if this contract holds exactly X ETH, allow withdrawal</em>. Or: <em>if balance is zero, this pool is empty</em>. These checks assume the balance can only change through the contract's own sanctioned functions. <code>SELFDESTRUCT</code> breaks that assumption from the outside, using a legitimate opcode exactly as specified.</p><p>It was designed as a <em>cleanup tool</em>. The protocol originally gave you a gas refund for using it, as an incentive to delete unused contracts and reduce chain bloat—a mechanism removed separately in EIP-3529 (London, 2021), years before the behavior itself was constrained. The designers were thinking about lifecycle management. Not weaponized Ether injection.</p><p>By 2024, <code>SELFDESTRUCT</code> had nine years of dependents. You cannot remove it. So the Ethereum community did what it always does when it cannot delete: constrained it. EIP-6780 [10], included in the Cancun upgrade, changed the rules: full destruction only if called within the <em>same transaction</em> that created the contract. On any existing contract, it transfers the Ether and stops. The code remains. The storage remains.</p><p>Why this specific rule? The legitimate use cases—deploy-time cleanup, one-shot factory patterns—still work. The weaponized use case is defused: the Ether transfer no longer carries the threat of deletion. There is also an architectural reason. The Cancun upgrade began restructuring how Ethereum nodes store state, and the original <code>SELFDESTRUCT</code> behavior—immediately wipe all storage—is incompatible with a storage model that cannot guarantee instant deletion. EIP-6780 was not just a security patch. It was a prerequisite.</p><p>The TNT is still in the toolbar. It just does not explode anymore.</p><hr><h2 id="h-11-push0-one-opcode-billions-saved" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">11. <code>PUSH0</code> — One Opcode, Billions Saved</h2><p>This one is not an attack. But it is the most honest illustration of how the EVM actually evolves.</p><p>Pull all bytecode executing on Ethereum mainnet and start counting. Roughly 11.5% of all <code>PUSH</code> operations push the constant value zero [11]—not a variable, not a computed result. Just zero. Compilers emit <code>PUSH1 0x00</code> constantly for initializing variables, clearing slots, setting default return values.</p><p><code>PUSH1 0x00</code> costs 3 gas and takes 2 bytes. The value being pushed is always the same. There is no reason the EVM should treat it like arbitrary data.</p><p>So someone wrote an EIP. <code>PUSH0</code>—an opcode that pushes zero, costs 2 gas, and takes 1 byte. One byte saved. One gas saved. Multiply that across billions of executions, and the aggregate savings are real. EIP-3855. Shanghai, 2023. Done. [11]</p><p>No drama. No security incident. No attacker. Just someone who counted carefully.</p><p>If zero is common enough to deserve its own opcode, a natural follow-up: what about other high-frequency patterns? Run byte pair encoding—BPE, the compression algorithm behind tokenizers—on all bytecode executing on mainnet, and identify the most common sequences. Give those sequences cheaper representations. The efficiency gains would compound across everything, not just zero-pushes.</p><p>The problem is structural. EVM bytecode must be directly executable, opcode by opcode, on every node simultaneously. BPE requires a shared dictionary—a reference that tells each node what a compressed token means. But the EVM has no mechanism for shared references. Common sequences in one contract are not necessarily common in another, and a universal scheme would require either per-contract dictionaries (stateful, expensive) or an approximate dictionary (defeating the purpose). Determinism requires that encoding be explicit and stateless. A compression scheme requires a shared external reference. Those two requirements are incompatible.</p><p><code>PUSH0</code> works precisely because it needs no dictionary. The value is universally constant. There is nothing to decode.</p><hr><h2 id="h-12-when-backward-compatibility-becomes-a-governance-constraint" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">12. When Backward Compatibility Becomes a Governance Constraint</h2><p>Four opcodes. Four types of pressure: an environmental assumption that required fixes at two separate layers of the stack, a semantic assumption that broke when gas costs changed beneath it, a security assumption that was weaponized by design, and an efficiency assumption that accumulated silently until the data made it visible.</p><br><table><colgroup><col><col><col><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>#</p></th><th colspan="1" rowspan="1"><p>Opcode</p></th><th colspan="1" rowspan="1"><p>Upgrade</p></th><th colspan="1" rowspan="1"><p>Pressure Type</p></th></tr><tr><td colspan="1" rowspan="1"><p>1</p></td><td colspan="1" rowspan="1"><p><code>CHAINID</code></p></td><td colspan="1" rowspan="1"><p>Istanbul (2019)</p></td><td colspan="1" rowspan="1"><p>Environmental</p></td></tr><tr><td colspan="1" rowspan="1"><p>2</p></td><td colspan="1" rowspan="1"><p><code>SSTORE</code></p></td><td colspan="1" rowspan="1"><p>Constantinople → St. Petersburg (2019)</p></td><td colspan="1" rowspan="1"><p>Semantic</p></td></tr><tr><td colspan="1" rowspan="1"><p>3</p></td><td colspan="1" rowspan="1"><p><code>SELFDESTRUCT</code></p></td><td colspan="1" rowspan="1"><p>Frontier (2015) → Cancun (2024)</p></td><td colspan="1" rowspan="1"><p>Security</p></td></tr><tr><td colspan="1" rowspan="1"><p>4</p></td><td colspan="1" rowspan="1"><p><code>PUSH0</code></p></td><td colspan="1" rowspan="1"><p>Shanghai (2023)</p></td><td colspan="1" rowspan="1"><p>Efficiency</p></td></tr></tbody></table><br><p>In each case, the response followed the same pattern. The original opcode could not be removed. Its behavior could not be retroactively changed. The machine could only be extended—new opcodes added, old behaviors constrained at the edges—while everything already carved into the stone continued executing as written.</p><p>This is not a failure of engineering. It is the cost of the property that makes Ethereum useful: the guarantee that code deployed today will execute the same way indefinitely. You cannot have that guarantee and also have the freedom to fix mistakes cleanly. Every upgrade since Frontier has been a negotiation with that constraint.</p><p>What these four cases do not show is what happens when the constraint is not technical but architectural—when the change required is not a new opcode but a new <em>structure</em> for the bytecode container itself.</p><hr><h2 id="h-13-eof-and-risc-v-from-restructuring-to-replacement" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">13. EOF and RISC-V — From Restructuring to Replacement</h2><p>EVM Object Format (EOF) was the most ambitious EVM change attempted since Frontier. It did not add opcodes. It restructured the container that holds them—introducing versioning, separating code from data sections, enabling deploy-time validation instead of runtime validation. [12] For new contracts, the benefits were concrete: cheaper deployment, earlier error detection, smaller bytecode. For old contracts, nothing would change—legacy and versioned bytecode would coexist.</p><p>In 2025, EOF was removed from the Fusaka upgrade after years of development. Core developers could not reach consensus. "We don't agree, and we're not coming to an agreement about EOF anymore, and so it has to go out," core developer Marius van der Wijden said at the final decision call. [13] The technical case was not seriously contested. The disagreement was about something harder to resolve.</p><p>EOF required that several new opcodes—<code>CALLF</code>, <code>JUMPF</code>, and others enabling the structured control flow that EOF was designed to support—be available exclusively to EOF-format contracts. Legacy contracts could not use them. This was not arbitrary: the opcodes relied on the validation guarantees that EOF's deploy-time checking provided, guarantees that legacy bytecode could not satisfy. But the practical effect was migration pressure. Developers who wanted access to those opcodes had to move to EOF format. Some stakeholders read this as reasonable incentive—adoption had to come from somewhere. Others read it as coercion: the network penalizing contracts for the format they were written in, using opcode access as leverage. Both readings were defensible. Neither side was wrong on the technical merits. That is precisely why the disagreement could not be resolved: it was not a dispute about facts, but about what the network is permitted to do to its existing participants.</p><p>The constraint that has governed every opcode change since 2015—the machine can only be extended, never corrected—has propagated upward. It is no longer just technical. It is social. Every new contract deployed under the current format is another argument against restructuring. The surface area of "things that cannot be disturbed" grows with every block.</p><p>There is a larger question now on the table. Vitalik Buterin has proposed migrating Ethereum's execution environment to RISC-V—an open, modular processor architecture used across smartphones, servers, and embedded systems. [14] If this direction succeeds, the EVM itself would eventually be replaced by a RISC-V-based VM. Not restructured. Replaced.</p><p>The proposal does not claim that RISC-V is categorically superior for all use cases. The argument is simpler: RISC-V is a widely-understood, extensively-tooled architecture with a large existing ecosystem. Moving to it would allow Ethereum's execution environment to benefit from compiler toolchains, formal verification frameworks, and optimization work that already exists outside the Ethereum ecosystem, rather than rebuilding those capabilities for a bespoke VM.</p><p>The backward-compatibility question is answered by layering. Legacy EVM contracts would continue to execute through an EVM interpreter implemented in RISC-V—the old machine running as software on the new one. New contracts would target RISC-V natively. The two execution environments would coexist, exactly as EOF proposed for legacy and versioned bytecode, but at a larger scale.</p><p>Whether this is achievable is a question that does not yet have an answer. The EVM interpreter layer introduces its own complexity. The migration path requires client teams to implement and maintain two runtimes simultaneously during a transition period of unknown length. And the governance problem that sank EOF does not disappear: a change of this scale would require the same near-unanimous consensus, across the same distributed set of stakeholders, that EOF could not achieve.</p><p>But the RISC-V proposal is not primarily an engineering proposal. It is an argument about the shape of the constraint. The claim is that the EVM's limitations are not intrinsic to decentralized execution—they are specific to this particular VM's design—and that a sufficiently well-designed replacement could inherit Ethereum's permanence guarantees without inheriting the accumulated technical debt.</p><p>That argument may be correct. It may also be that the constraint is not in the VM design but in the governance structure around it, in which case replacing the VM solves the wrong problem.</p><p>The question RISC-V raises is more fundamental: whether the machine can be replaced without breaking what it has already carved, and whether the network that built the machine can agree on anything large enough to try.</p><p>There is a version of this story where the question becomes moot. L2 execution environments—Arbitrum Stylus accepting Rust and C++, StarkNet running Cairo, zkSync's zkEVM diverging from EVM semantics at the proof layer—exist precisely because L1 evolution is this constrained. Innovation that cannot happen at L1 does not stop; it relocates. If RISC-V does not succeed, or does not succeed fast enough, the EVM does not disappear. It becomes a settlement layer—a compatibility surface that legacy contracts execute against while real execution happens elsewhere. That is not obviously a bad outcome. But it is a different one than Ethereum's designers intended, and it is already partially underway. The RISC-V proposal is, among other things, an attempt to reclaim that ground before the center of gravity shifts permanently.</p><hr><h2 id="h-references" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">References</h2><p>[1] Andreas M. Antonopoulos and Gavin Wood, <em>Mastering Ethereum</em>, "Appendix A: Ethereum Fork History." <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://cypherpunks-core.github.io/ethereumbook/appdx-forks-history.html">https://cypherpunks-core.github.io/ethereumbook/appdx-forks-history.html</a> — Primary source for: 3.6 million ETH drained from The DAO; hard fork executed at block 1,920,000 on July 20, 2016; ETC initial mining power approximately 10% of the combined network.</p><p>[2] CoinDesk, "CoinDesk Turns 10: How The DAO Hack Changed Ethereum and Crypto," May 9, 2023. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.coindesk.com/consensus-magazine/2023/05/09/coindesk-turns-10-how-the-dao-hack-changed-ethereum-and-crypto">https://www.coindesk.com/consensus-magazine/2023/05/09/coindesk-turns-10-how-the-dao-hack-changed-ethereum-and-crypto</a></p><p>[3] Ethereum Improvement Proposals, EIP-155: Simple replay attack protection, 2016. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-155">https://eips.ethereum.org/EIPS/eip-155</a> — Introduced chain ID into transaction signatures via the Spurious Dragon upgrade (November 2016), closing the transaction-layer replay attack four months after the DAO fork.</p><p>[4] Ethereum Improvement Proposals, EIP-1344: ChainID opcode, 2018. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-1344">https://eips.ethereum.org/EIPS/eip-1344</a></p><p>[5] Ethereum Foundation, "Ethereum Launches," July 30, 2015. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blog.ethereum.org/2015/07/30/ethereum-launches">https://blog.ethereum.org/2015/07/30/ethereum-launches</a> — Official announcement of the Frontier release, marking the genesis block and the initial live deployment of the EVM.</p><p>[6] Ethereum Foundation, "Ethereum Constantinople Upgrade Announcement," January 11, 2019. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blog.ethereum.org/2019/01/11/ethereum-constantinople-upgrade-announcement">https://blog.ethereum.org/2019/01/11/ethereum-constantinople-upgrade-announcement</a> — Official announcement confirming Constantinople scheduled for block 7,080,000.</p><p>[7] ChainSecurity, "Constantinople Enables New Reentrancy Attack," January 15, 2019. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/chainsecurity/constantinople-enables-new-reentrancy-attack-ace4088297d9">https://medium.com/chainsecurity/constantinople-enables-new-reentrancy-attack-ace4088297d9</a></p><p>[8] Ethereum Improvement Proposals, EIP-1283: Net gas metering for SSTORE without dirty maps, 2018. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-1283">https://eips.ethereum.org/EIPS/eip-1283</a></p><p>[9] ChainSecurity, "Constantinople Security Update," January 2019. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://medium.com/chainsecurity/constantinople-security-update-3d02017747f2">https://medium.com/chainsecurity/constantinople-security-update-3d02017747f2 </a>— Follow-up analysis stating the broader lesson after the upgrade delay; distinct from the original vulnerability disclosure cited as [7].</p><p>[10] Ethereum Improvement Proposals, EIP-6780: SELFDESTRUCT only in same transaction, 2023. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-6780">https://eips.ethereum.org/EIPS/eip-6780</a></p><p>[11] Ethereum Improvement Proposals, EIP-3855: PUSH0 instruction, 2021. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-3855">https://eips.ethereum.org/EIPS/eip-3855</a></p><p>[12] Ethereum Improvement Proposals, EIP-3540: EOF - EVM Object Format v1, 2021. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://eips.ethereum.org/EIPS/eip-3540">https://eips.ethereum.org/EIPS/eip-3540</a></p><p>[13] Blockworks, "Ethereum Consensus Shifts on EVM Upgrade," June 9, 2025. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://blockworks.co/news/ethereum-consensus-evm-upgrade-fusaka-devs">https://blockworks.co/news/ethereum-consensus-evm-upgrade-fusaka-devs</a></p><p>[14] Vitalik Buterin, "Ethereum's Execution Layer: Long-Run Architecture," Ethereum Research, 2025. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethereum-magicians.org/t/long-term-l1-execution-layer-proposal-replace-the-evm-with-risc-v/23617">https://ethereum-magicians.org/t/long-term-l1-execution-layer-proposal-replace-the-evm-with-risc-v/23617</a></p>]]></content:encoded>
            <author>chengmarc@newsletter.paragraph.com (chengmarc.eth)</author>
            <category>ethereum</category>
            <category>evm</category>
            <category>blockchain</category>
            <category>opcodes</category>
            <category>smartcontracts</category>
            <category>solidity</category>
            <category>bytecode</category>
            <category>web3</category>
            <category>layer1</category>
            <category>l1</category>
            <category>layer2</category>
            <category>l2</category>
            <category>protocol</category>
            <category>hardfork</category>
            <category>backwardcompatibility</category>
            <category>governance</category>
            <category>consensus</category>
            <category>eip</category>
            <category>selfdestruct</category>
            <category>sstore</category>
            <category>chainid</category>
            <category>push0</category>
            <category>eof</category>
            <category>risc-v</category>
            <category>dao</category>
            <category>etc</category>
            <category>eth</category>
            <category>replayattack</category>
            <category>gasoptimization</category>
            <category>defi</category>
            <category>infrastructure</category>
            <category>decentralization</category>
            <category>security</category>
            <enclosure url="https://storage.googleapis.com/papyrus_images/9a57e14b3c3bbed9f6cd2fdb241c331739b4028bc2baf5d9f4769fda02a94432.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[When x·y = k Breaks: A Mechanism Derivation of On-Chain Perpetuals, Funding Rates, and a Step-by-Step Replication of a $4.9M Exploit]]></title>
            <link>https://paragraph.com/@chengmarc/when-x·y=k-breaks</link>
            <guid>QXBfSqix5YUW0rnP647k</guid>
            <pubDate>Thu, 30 Apr 2026 15:18:12 GMT</pubDate>
            <description><![CDATA[Uniswap's invariant is unbreakable because it conserves something real. Perpetuals have no equivalent conservation law — so builders replaced it with a cost function, a funding rate, and an 8-hour snapshot window. That snapshot window is a gap. This piece derives exactly how wide the gap is, what it costs to exploit it, and why Hyperliquid has been hit three times without fixing the root cause. The math is not complicated. The consequences are.]]></description>
            <content:encoded><![CDATA[<h2 id="h-1-the-billion-dollar-formula-you-could-have-derived-in-high-school" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">1. The Billion-Dollar Formula You Could Have Derived in High School</h2><p>I had been trading on Uniswap for years before I sat down to derive how it actually worked. Tokens that never made it onto centralized exchanges, positions on obscure chains — Uniswap was infrastructure I used without thinking about. When I finally worked through the math, my first reaction was: <em>this is it?</em></p><p>Uniswap has settled hundreds of billions of dollars in trades. It has survived multiple market collapses, regulatory pressure, and the death of protocols far more sophisticated in design. The core pricing mechanism is:</p><p>$$x \cdot y = k$$</p><p>Two asset reserves, $$x$$ and $$y$$. A constant $$k$$ maintained across every trade. To swap $$\Delta x$$ of asset $$X$$ for some quantity of $$Y$$:</p><p>$$(x + \Delta x)(y - \Delta y) = k$$</p><p>$$\Delta y = \frac{y \cdot \Delta x}{x + \Delta x}$$</p><p>High school algebra. No order book, no counterparty coordination, no off-chain matching engine. The invariant <em>is</em> the market maker. [1]</p><p>The mechanism's durability follows directly from its constraint structure. The pool holds real assets at all times. $$k$$ can only increase via fees. There is no liability side to the balance sheet — no promise that can be honored only conditionally. This is the structural distinction between Uniswap and Luna: Luna's stability mechanism required the protocol to honor a peg its assets could not always cover. Confidence breaks, the liability exceeds assets, the spiral is mechanical. Uniswap has no equivalent failure mode because it has no equivalent promise.</p><p>The natural question is whether this extends to perpetual contracts. It does not, for reasons that are also structural. Identifying exactly where the invariant breaks — and what replaces it — is the subject of the rest of this piece.</p><hr><h2 id="h-2-when-conservation-laws-have-nothing-left-to-conserve" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">2. When Conservation Laws Have Nothing Left to Conserve</h2><p>Start with what $$x \cdot y = k$$ actually conserves. When you buy $$Y$$ from a spot AMM, the pool transfers real Y from its balance to you. Nominal exposure and real assets are the same thing. The invariant holds because the quantities it tracks — reserves — are physical.</p><p>Now ask what a perpetual contract position actually is. Not a claim on a real asset in the pool. A claim on a <em>future price difference</em>. The pool never transfers the underlying — it settles the delta between entry price and exit price in collateral.</p><p>This means the aggregate notional exposure of the book — total longs $$L$$ plus total shorts $$S$$ — has no upper bound imposed by the pool's real assets. A pool with collateral $$V$$ can have $$L + S \gg V$$. That is the point of leverage.</p><p>So what happens if you try to apply $$x \cdot y = k$$ to $$L$$ and $$S$$ directly? Let $$x = L$$, $$y = S$$. The invariant says $$L \cdot S = k$$. Now a trader opens a large long, pushing $$L$$ up. The invariant forces $$S$$ down — but $$S$$ is not a reserve the pool controls. It is the aggregate of other traders' positions. The pool cannot conjure short interest to balance the book. Three things follow immediately:</p><ul><li><p><strong>No real-asset anchor.</strong> Virtual reserves track nominal positions, not collateral. The pool can appear balanced on paper while being structurally insolvent.</p></li><li><p><strong>No conservation law to enforce.</strong> $$x \cdot y = k$$ requires both sides to be quantities the pool holds. The pool holds collateral — it does not hold $$L$$ or $$S$$.</p></li><li><p><strong>Asymmetric unwind risk.</strong> If the dominant side exits simultaneously, settlement obligations exceed available collateral. The invariant provides no mechanism to prevent this.</p></li></ul><p>The constant product formula is a conservation law. Perpetuals have no equivalent quantity to conserve — what they need is a mechanism to penalize imbalance.</p><hr><h2 id="h-3-what-the-pool-actually-needs-to-track" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">3. What the Pool Actually Needs to Track</h2><p>We need to replace $$x \cdot y = k$$ with something that works for perpetuals. Start by asking: what is the minimal quantity the pool actually needs to track?</p><p>Not the absolute size of $$L$$ or $$S$$ individually — those numbers alone tell you nothing about the pool's exposure. What matters is their <em>difference</em>, normalized against their <em>sum</em>.</p><p>First, a note on what $$L$$ and $$S$$ actually are. Define long open interest $$L$$ as the total notional value of all outstanding long positions, and short open interest $$S$$ as the total notional value of all outstanding short positions, both denominated in USD. Unlike in traditional order book futures markets — where a contract only comes into existence when a buyer and seller are matched, so any unmatched order simply waits on the book and never enters open interest; $$L = S$$ is therefore an accounting identity, not an equilibrium condition — a perpetual AMM absorbs the net imbalance directly. $$L$$ and $$S$$ are therefore independent quantities. The pool holds collateral; it does not hold the underlying asset. The difference $$L - S$$ is the net directional exposure the pool is implicitly carrying.</p><p>Define the book skew:</p><p>$$\delta = \frac{L - S}{L + S}$$</p><p>The denominator $$L + S$$ is the gross open interest — the total bilateral notional exposure in the pool. Since $$L, S \geq 0$$, we always have $$|L - S| \leq L + S$$, so:</p><p>$$\delta \in (-1, 1)$$</p><p>This follows directly from the definition, without any external constraint or position cap. When $$\delta = 0$$, the book is balanced. When $$\delta \to 1$$, the book is overwhelmingly long. When $$\delta \to -1$$, overwhelmingly short.</p><p>Now ask what $$\delta$$ actually measures — and what it does not.</p><p>$$\delta$$ measures <strong>directional imbalance</strong>: which side dominates the book, and by how much relative to total bilateral exposure. This is useful. A pool with $$\delta$$ near zero is structurally safer than one with $$\delta$$ near $$\pm 1$$.</p><p>What $$\delta$$ does <em>not</em> measure is <strong>solvency under stress</strong>. $$L$$ and $$S$$ are notional values — the face value of positions, not the pool's actual payment obligations. If all longs are liquidated simultaneously during a sharp price move, the pool's settlement obligation is:</p><p>$$\text{obligation} = L \cdot \frac{|P_{\text{exit}} - P_{\text{entry}}|}{P_{\text{entry}}}$$</p><p>where $$P_{\text{entry}}$$ and $$P_{\text{exit}}$$ are the average entry and liquidation prices across all long positions. This number scales with both notional exposure and price displacement — neither of which is bounded by the gross open interest. A pool with $$\delta = 0$$ and $$L = S$$ facing a 50% price move has a settlement obligation of $$0.5L$$ on each side. Its actual collateral may be a fraction of that. $$\delta = 0$$ does not mean the pool can survive a correlated unwind. It means the book is directionally balanced at this moment, under current prices.</p><p>This is the distinction between <em>directional risk</em> and <em>solvency risk</em>. $$\delta$$ measures the former. When $$\delta \approx 0$$, the pool's net settlement obligation approaches zero regardless of total open interest — longs and shorts cancel out. Solvency risk is only material when $$\delta$$ drifts significantly, or when a correlated unwind outpaces the liquidation engine. The funding rate, derived in the next section, is what keeps $$\delta$$ near zero in the first place.</p><p>This distinction also matters for what the cost function can and cannot guarantee, which is the subject of the next section.</p><p>Note that $$\delta$$ is a <em>signed</em> quantity. This matters for the cost function below.</p><hr><h2 id="h-4-why-binance-has-never-gone-bankrupt-on-perpetuals" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">4. Why Binance Has Never Gone Bankrupt on Perpetuals</h2><p>We have $$\delta$$ as a measure of book imbalance. Now ask: what should the pool do about it?</p><p>The pool cannot force traders to close positions. What it can do is make it increasingly expensive to push the book further out of balance — and increasingly cheap to push it back. If opening a long position when $$\delta &gt; 0$$ costs more than when $$\delta = 0$$, rational traders will arbitrage the book toward balance. This gives us the shape of the cost function:</p><ul><li><p>At $$\delta = 0$$: baseline cost $$c_0$$</p></li><li><p>As $$\delta \to \pm 1$$: cost must diverge to infinity — no finite capital should be able to corner the book entirely</p></li></ul><p>A function that satisfies both conditions:</p><p>$$\text{cost}(\delta) = \frac{c_0}{1 - \delta^2}$$</p><p>As $$\delta \to \pm 1$$:</p><p>$$\lim_{\delta \to 1^-} \frac{c_0}{1 - \delta^2} = +\infty$$</p><p>This is the perpetuals analogue of $$x \cdot y = k$$: just as infinite capital would be required to drain one side of a spot pool entirely, infinite capital is required to push $$\delta$$ to its theoretical maximum. The pool cannot be cornered.</p><p>The marginal cost of an incremental long position of size $$d\ell$$ is:</p><p>$$\frac{d(\text{cost})}{d\delta} \cdot \frac{d\delta}{d\ell} = \frac{2c_0\delta}{(1-\delta^2)^2} \cdot \frac{1}{L+S}$$</p><p>where the factor $$1/(L+S)$$ follows from $$d\delta/dL = 1/(L+S)$$ — opening a long of size $$d\ell$$ increases $$L$$ by $$d\ell$$, shifting $$\delta$$ by $$d\ell/(L+S)$$. Positive when $$\delta &gt; 0$$ — adding more longs to an already long-heavy book costs extra. Negative when $$\delta &lt; 0$$ — adding longs when the book is short-heavy is effectively subsidized, because it moves toward balance. The function is symmetric and convex in $$\delta$$.</p><p>Now ask a second question: what about positions that are already open? The opening cost penalizes the act of creating imbalance. But a trader who opened a long yesterday when $$\delta$$ was small is still holding that position today when $$\delta$$ is large. The opening cost alone is insufficient — the pool also needs a continuous charge on the <em>holding</em> of imbalanced positions.</p><p>This gives a natural definition for the instantaneous funding rate:</p><p>$$r(\delta) = r_0 \cdot \frac{\delta}{1 - \delta^2}$$</p><p>When $$\delta = 0$$, the funding rate is zero — perfectly balanced books require no correction. As imbalance grows, the funding rate grows superlinearly, making it increasingly expensive to hold the dominant side. The dominant side pays the minority side. The mechanism self-corrects.</p><p>Voilà. We just derived why funding rates must exist — and why Binance, despite running hundreds of billions in perpetual exposure, has never been bankrupted by it.</p><p>The argument is structural, but the causal order matters. $$\delta \approx 0$$ is not the premise — it is the equilibrium that $$r(\delta)$$ produces. Because holding the dominant side incurs a continuous payment to the minority side, rational traders have a standing incentive to rebalance the book. When that equilibrium holds, any price movement results in longs losing exactly what shorts gain, and Binance's net settlement obligation is zero. It is not absorbing directional risk; it is a clearinghouse between two matched sides.</p><p>The failure condition: if the funding signal is suppressed — through opaque internal netting or misreporting — $$\delta$$ can drift without triggering correction. The exchange still appears to be a clearinghouse while accumulating net directional exposure. FTX's internal risk models reported matched books while the exchange held billions in net long FTT exposure. The mechanism is only as reliable as the signal it depends on.</p><p>Binance's actual funding rate formula looks different from $$r(\delta)$$. Rather than measuring position imbalance directly, it uses the deviation between the perpetual's mark price and the spot index price as a proxy — clamped to a cap to prevent runaway payments. [2] The intuition is the same: when longs dominate, buying pressure pushes the perpetual price above spot, the premium index goes positive, and longs pay shorts. When shorts dominate, the reverse. Price deviation is an observable market signal for $$\delta$$ — easier to compute on-chain than aggregating all open positions. The proxy is imperfect, but the corrective direction is identical.</p><p>The funding rate is the only self-consistent solution to the imbalance problem, regardless of how you measure that imbalance. Every exchange that runs perpetuals arrives at the same place.</p><hr><h2 id="h-5-what-if-we-rebuilt-binance-perpetuals-without-binance" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">5. What If We Rebuilt Binance Perpetuals Without Binance?</h2><p>Binance's mechanism works. But it runs on a centralized server — one system, one state, no consensus required. And if you have been following the derivation so far, a thought might have occurred to you: this is just math. $$\delta$$, a cost function, a funding rate. The formula fits on half a page. What if you put this on-chain? What if you built the decentralized version — permissionless, trustless, no Binance in the middle? You could be first. This could be a company.</p><p>It turns out someone had the same thought. Several someones. dYdX launched in 2021. Hyperliquid followed. The on-chain perpetuals AMM already exists, and it is already running billions in volume. Sadly, you are not first.</p><p>It just does not work quite the way you would imagine.</p><p>The problem surfaces the moment you try to maintain a global $$\delta$$ on-chain. In Binance's centralized system, updating $$L$$, $$S$$, and $$\delta$$ after every trade is trivial — one process, one state, sequential writes. On-chain, every state update is a transaction that must be included in a block, executed by every node, and finalized by consensus. Two transactions cannot atomically and simultaneously update $$L$$, $$S$$, and $$\delta$$ without one reading a stale value or the other being blocked. This is not an EVM quirk — it is a fundamental property of any system maintaining a single global consensus state.</p><p>The consequence is a trilemma. You cannot have all three simultaneously:</p><ul><li><p><strong>Global consistency</strong>: every participant sees the same $$\delta$$</p></li><li><p><strong>Real-time continuity</strong>: $$\delta$$ updates with every trade</p></li><li><p><strong>High throughput</strong>: many trades processed per block</p></li></ul><p>This is the perpetuals AMM equivalent of the CAP theorem. Pick two.</p><p>The 8-hour funding rate snapshot — used by dYdX, Hyperliquid, and virtually every production perpetuals protocol — is the engineering resolution. Instead of computing $$\delta$$ continuously, the protocol:</p><ol><li><p>Snapshots $$L$$, $$S$$ at fixed intervals $$T$$ (typically 8 hours)</p></li><li><p>Computes the time-weighted average imbalance over the window:</p></li></ol><p>$$\bar{\delta} = \frac{1}{T}\int_0^T \delta(t) , dt$$</p><ol start="3"><li><p>Settles the funding payment based on $$\bar{\delta}$$</p></li></ol><p>This recovers global consistency and high throughput at the cost of real-time continuity.</p><p>The 8-hour number comes from BitMEX, which invented the perpetual swap in 2016 and chose it as an arbitrary design parameter to approximate daily lending rates divided by three. [3][4] Binance copied it. Every exchange that followed copied Binance. The window predates on-chain perpetuals entirely.</p><p>For Binance, $$T$$ is a policy parameter it can adjust. Under extreme volatility, Binance has shortened the settlement interval to one hour. [5] For an on-chain protocol, the serial write constraint turns $$T$$ into a structural floor. The same attack surface exists on Binance; Binance can close it by turning a dial. The on-chain protocol cannot.</p><hr><h2 id="h-6-a-thought-experiment-with-real-money" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">6. A Thought Experiment With Real Money</h2><p>You have been following the derivation. You understand $$\delta$$. You understand the 8-hour snapshot window. You understand that dYdX and Hyperliquid are on-chain — every position, every settlement, every liquidation is a public transaction on a public ledger. No KYC. No one can trace a wallet to a person.</p><p>A thought occurs to you. A malicious one.</p><p>The snapshot window is $$[0, T]$$, eight hours long. A snapshot just cleared — meaning the funding rate just settled to near zero. The <em>next</em> settlement is eight hours away. During this window, your holding cost is determined not by the instantaneous $$r(\delta)$$ you create, but by the time-weighted average $$\bar{\delta} = \frac{1}{T}\int \delta(t),dt$$ across the entire window. If you enter at $$t = 0$$, the integral starts from zero. For the first hours of the window, $$\bar{\delta} \ll \delta$$ — you are holding a massively imbalanced position at a fraction of its steady-state cost. The cost function penalizes opening at high $$\delta$$. It does not penalize <em>holding</em> at high $$\delta$$ until the window closes.</p><p>What if you used that window?</p><p>Here is what the attack looks like, step by step:</p><p><strong>Step 1: Enter immediately after the snapshot.</strong> Open a large long position the moment a funding snapshot clears, pushing $$\delta$$ significantly toward $$+1$$. The cost function makes entry expensive — but expensive is not infinite, and the carry cost for the next eight hours is near zero. Your capital is at risk for one window. The funding clock just reset.</p><p><strong>Step 2: Hold and distort the mark price.</strong> A concentrated long position creates sustained buying pressure on the perpetual. The mark price — computed as a TWAP over the window — begins to diverge from the spot index price. Other traders' long positions are now marked at inflated prices. Their short positions are approaching liquidation thresholds.</p><p><strong>Step 3: Trigger liquidations.</strong> As the mark price displacement grows, undercollateralized short positions get liquidated — settled against your manipulated mark. The insurance fund absorbs the difference between the manipulated mark and the fair value. You collect the P&amp;L from the displacement.</p><p><strong>Step 4: Exit before settlement.</strong> Close your position before the snapshot. Your cost: the funding payment for one window, plus execution slippage. Your upside: the P&amp;L extracted from liquidations exceeds the cost of capital.</p><p>The condition for a profitable attack is simply:</p><p>$$\text{PnL} &gt; \text{cost}(\delta_{\text{attack}}) \cdot T + \text{slippage}$$</p><p>The 8-hour window determines how long you must hold capital at risk. Shorten $$T$$ and the attack becomes harder to sustain. Lengthen $$T$$ and the attack window grows. There is no value of $$T$$ that eliminates the surface entirely — only values that change its economics.</p><p>Even among people entertaining malicious thoughts, you are not first. How unfortunate. The attack vector was already in production before you finished reading this section.</p><hr><h2 id="h-7-the-blockchain-is-not-anonymous-it-is-pseudonymous" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">7. The Blockchain Is Not Anonymous. It Is Pseudonymous.</h2><p>On November 12, 2025, someone withdrew 3 million in USDC from OKX, split it across 19 wallets, bridged to Hyperliquid via Arbitrum, and opened 20–30 million in leveraged long positions on POPCAT — a Solana-based memecoin. They placed a 20 million buy wall near 0.21 to simulate organic demand, pushing the price up roughly 30%. Then they pulled the buy wall. POPCAT crashed 43% in minutes. Cascading liquidations followed. Hyperliquid's community-owned HLP vault absorbed $4.9 million in bad debt — roughly three months of prior profits, gone in an afternoon. [6]</p><p>This was not a smart contract exploit. The protocol functioned exactly as designed. It was a mechanism exploit — and the mechanism is the one described in Section 6. The attacker entered immediately after a funding snapshot, when carry cost on the imbalanced position was near zero. They held through the window, distorting the mark price via sustained buying pressure. Cascading liquidations followed as undercollateralized shorts hit their thresholds. Each of these steps follows directly from the attack surface derived above.</p><p>The one departure from Section 6's model is where the profit landed. Section 6 describes collecting P&amp;L as the liquidation counterparty on-chain. In practice, that leg is structurally crowded out: the HLP vault acts as mandatory backstop for positions too large to be absorbed by the order book, which means the attacker cannot straightforwardly stand on the other side of the liquidations they trigger. The attacker did not attempt to collect on-chain. Instead, the on-chain position served only to distort the mark price. The actual profit came from opposing short positions held simultaneously on OKX and Bybit. The on-chain loss — $3–4 million in collateral — was not a cost. It was the weapon.</p><p><strong>Was the attacker caught?</strong> Not formally. But recall the premise from Section 6: <em>no one can track me down on-chain</em>. That premise was wrong. Blockchain analyst Specter published an on-chain investigation the following day tracing the 26 wallets through OKX and Bybit deposit addresses, cross-chain flows via Polygon and Ethereum, and wallet reuse from a prior August 2025 manipulation. The trail led to BTX Capital, a U.S.-based crypto investment firm, and its founder Vanessa Cao. [7] The blockchain is not anonymous. It is pseudonymous — and pseudonymity, given enough on-chain activity, is effectively traceable.</p><p>No charges were filed. Vanessa Cao publicly denied involvement. [8]</p><p><strong>Was the vulnerability fixed?</strong> Hyperliquid responded by tightening leverage limits and position caps on low-liquidity assets. The snapshot window remains. The root cause — the structural gap between real-time $$\delta$$ and periodic settlement — was not addressed. What was patched was the symptom: the specific leverage ratio and position size that made POPCAT eligible. The mechanism that produced the eligibility was left intact.</p><p>It is worth noting that this was not the first time. POPCAT was Hyperliquid's third major manipulation event in 2025, following JELLYJELLY in March [9] and another incident in July. The fixes after the first two attacks did not prevent the third. Patching leverage limits on thin markets is not the same as fixing the mechanism. The attacker simply waited for the next eligible token.</p><p>The structural attack surface described in Section 6 remains open. If you have a few million dollars and the appetite for it, the playbook is sitting right here.</p><p>Most readers do not. If you found this article searching for a way to get rich quick, the unfortunate reality is that you are probably not the target demographic for a $3 million kamikaze trade. Too bad.</p><p>For those who are — the argument that more demonstrated exploits force the industry to take structural vulnerabilities seriously is, at minimum, not wrong. Hyperliquid did not patch the snapshot window after the first attack, or the second. Whether a fourth incident changes that calculus is an open question.</p><hr><h2 id="h-8-the-math-is-solved-the-infrastructure-isnt" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">8. The Math Is Solved. The Infrastructure Isn't.</h2><p>The snapshot window is an engineering compromise forced by the cost of on-chain computation. Which raises the obvious question: what if that cost dropped dramatically?</p><p>The theoretical fix is to embed the funding rate continuously into the cost function itself, eliminating the snapshot window entirely. Instead of settling funding periodically based on $$\bar{\delta}$$, the cost of <em>opening and holding</em> a position at imbalance level $$\delta$$ already prices in the expected funding burden:</p><p>$$\text{cost}(\delta, t) = \frac{c_0}{1 - \delta^2} + \int_0^t r(\delta(\tau)) , d\tau$$</p><p>Under this formulation, the snapshot window collapses to zero. Every block settles the continuous funding accrual. The attack window disappears, because there is no gap between current $$\delta$$ and settled funding.</p><p>The reason this has not been implemented on Ethereum mainnet is straightforward: evaluating $$\int r(\delta(\tau)),d\tau$$ requires storing every intermediate state of $$\delta(\tau)$$. On a chain where every storage write costs real money, this is prohibitive. The serial write problem from Section 5 resurfaces immediately.</p><p>But the constraint is economic in nature. A practical approximation: settle funding every block, with $$\delta$$ computed from the previous block's state. This reduces the attack window from 8 hours to one block time. On Ethereum mainnet, that is ~12 seconds — still an attack surface, but orders of magnitude smaller. On a high-throughput L2 with sub-cent transaction fees and 250ms block times, per-block funding settlement becomes not just viable but cheap.</p><p>This is the design space worth thinking about. The mechanism is fully derived. The math is not the bottleneck. The question is purely infrastructural: which L2 provides the execution environment where continuous $$\delta$$ settlement becomes economically feasible? What does the gas model look like? How does the serial write constraint behave at 100ms block times?</p><p>Nobody has fully committed to this in production yet. That is either a gap in the market or a warning sign. Probably worth figuring out which.</p><hr><h2 id="h-9-what-we-just-did" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">9. What We Just Did</h2><p>The chain above — from $$x \cdot y = k$$ to $$\delta$$, from $$\delta$$ to the cost function, from the cost function to the snapshot constraint, from the snapshot to the attack window, from the attack window to POPCAT — is not a series of independent observations. Each step follows structurally from the previous one.</p><p>We did not start with the attack. We started with the invariant, asked where it breaks, derived the replacement primitive, and followed the engineering constraints until an attack surface appeared naturally at the end of the chain. The three numbers that characterize the vulnerability — attack cost, window duration, mark price sensitivity — were not looked up. They were derived.</p><p>That is mechanism auditing. Not reading code for reentrancy bugs. Not running static analysis tools. Starting from first principles, tracing which design decisions create structural attack surfaces, and quantifying the minimum-cost exploit at each one.</p><p>The funding rate vulnerability is not in the funding rate calculation. It is in the decision to use a snapshot window — which is the only viable solution to the serial write constraint — which is caused by the requirement for global consistency. You cannot find this by reading the Solidity. You find it by understanding why the Solidity is written the way it is.</p><p>Three numbers. One chain of reasoning. That is the audit.</p><hr><h2 id="h-references" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">References</h2><p>[1] Hayden Adams, Noah Zinsmeister, Dan Robinson. "Uniswap v2 Core," March 2020. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://uniswap.org/whitepaper.pdf">https://uniswap.org/whitepaper.pdf</a></p><p>[2] Binance, "Introduction to Binance Futures Funding Rates." <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.binance.info/en/support/faq/detail/360033525031">https://www.binance.info/en/support/faq/detail/360033525031</a></p><p>[3] BitMEX, "Perpetual Contracts Guide." <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.services.bitmex.com/app/perpetualContractsGuide">https://www.services.bitmex.com/app/perpetualContractsGuide</a></p><p>[4] BitMEX, "Q3 2025 Derivatives Report: Funding Rates Structure." <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.bitmex.com/blog/2025q3-derivatives-report">https://www.bitmex.com/blog/2025q3-derivatives-report</a></p><p>[5] Binance, "Important Updates on Funding Rate Settlement Frequency," May 2, 2025. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.binance.com/en/support/announcement/detail/3243c81a35bd4f0c86a37315c3dc96cc">https://www.binance.com/en/support/announcement/detail/3243c81a35bd4f0c86a37315c3dc96cc</a></p><p>[6] CoinDesk, "Peak Degen Warfare: Alleged POPCAT Manipulation Hits Hyperliquid with $4.9M Loss," November 13, 2025. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.coindesk.com/markets/2025/11/13/peak-degen-warfare-alleged-popcat-manipulation-hits-hyperliquid-with-usd4-9m-loss">https://www.coindesk.com/markets/2025/11/13/peak-degen-warfare-alleged-popcat-manipulation-hits-hyperliquid-with-usd4-9m-loss</a></p><p>[7] Tekedia, "POPCAT Attack on Hyperliquid Linked to BTX Capital Founder Vanessa Cao," November 15, 2025. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.tekedia.com/popcat-attack-on-hyperliquid-linked-to-btx-capital-founder-vanessa-cao/">https://www.tekedia.com/popcat-attack-on-hyperliquid-linked-to-btx-capital-founder-vanessa-cao/</a></p><p>[8] Cryptopolitan, "BTX Capital's Vanessa Cao Denies Role in POPCAT Manipulation on Hyperliquid," November 14, 2025. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://www.cryptopolitan.com/btx-capital-vanessa-cao-popcat-manipulation/">https://www.cryptopolitan.com/btx-capital-vanessa-cao-popcat-manipulation/</a></p><p>[9] OAK Research, "Hyperliquid and the JELLY Attack: Context, Vulnerability and Team Solution," March 28, 2025. <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://oakresearch.io/en/analyses/investigations/hyperliquid-jelly-attack-context-vulnerability-team-solution">https://oakresearch.io/en/analyses/investigations/hyperliquid-jelly-attack-context-vulnerability-team-solution</a></p>]]></content:encoded>
            <author>chengmarc@newsletter.paragraph.com (chengmarc.eth)</author>
            <category>defi</category>
            <category>perpetuals</category>
            <category>amm</category>
            <category>hyperliquid</category>
            <category>on-chain</category>
            <category>crypto</category>
            <category>mechanism-design</category>
            <category>dydx</category>
            <category>funding-rate</category>
            <category>exploit</category>
            <category>web3</category>
            <category>blockchain</category>
            <category>quant</category>
            <category>trading</category>
            <category>liquidation</category>
            <category>uniswap</category>
            <category>data</category>
            <category>math</category>
            <category>security</category>
            <category>alpha</category>
            <enclosure url="https://storage.googleapis.com/papyrus_images/1c6b6d76da21dd439dabbfb95ddf4034087fda6279e5f979f4124f1ca70885a1.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>