Callisto Network
WebsiteSecurity DepartmentTwitter
  • Whitepaper
    • 🇮🇹Whitepaper (ITA)
    • 🇮🇳Whitepaper (TELUGU)
    • 🇮🇳Whitepaper (HINDI)
    • 🇨🇳Whitepaper (CN Traditional)
    • 🇭🇰Whitepaper (CN Simplified)
    • 🇫🇷Whitepaper (FR)
    • 🇵🇭Whitepaper (PH)
  • 📌Strategic Plan
  • Callisto Network Vision
  • 🚀Callisto Network Progress Tracker
  • 🗓️Ecosystem Reports
    • Callisto Monthly - February 2023
    • Callisto Monthly - January 2023
      • 🇮🇹Callisto Monthly - January 2023 (ITA)
      • 🇫🇷Callisto Monthly - January 2023 (FR)
      • 🇮🇳Callisto Monthly - January 2023 (TELUGU)
    • Callisto Monthly - December 2022
      • 🇮🇹Callisto Monthly - December 2022 (ITA)
      • 🇫🇷Callisto Monthly - December 2022 (FR)
      • 🇵🇭Callisto Monthly - December 2022 (PHI)
    • Callisto Monthly - November 2022
      • 🇫🇷Callisto Monthly - November 2022 (FR)
      • 🇮🇹Callisto Monthly - November 2022 (ITA)
      • 🇮🇳Callisto Monthly - November 2022 (TELEGU)
    • Callisto Monthly - October 2022
      • 🇮🇹Callisto Monthly - October 2022 (ITA)
      • 🇫🇷Callisto Monthly - October 2022 (FR)
      • 🇵🇭Callisto Monthly - October 2022 (PHI)
      • 🇨🇳Callisto Monthly - October 2022 (CN Simplified)
      • 🇭🇰Callisto Monthly - October 2022 (CN Traditional)
      • 🇷🇺Monthly - October 2022 (RU)
    • Callisto Monthly - September 2022
      • 🇮🇹Callisto Monthly - September 2022 (ITA)
      • 🇫🇷Callisto Monthly - September 2022 (FR)
      • 🇵🇭Callisto Monthly - September 2022 (PHI)
      • 🇨🇳Callisto Monthly - September 2022 (CN Simplified)
      • 🇭🇰Callisto Monthly - September 2022 (CN Traditional)
    • Callisto Monthly - August 2022
      • 🇮🇹Callisto Monthly - August 2022 (ITA)
      • 🇫🇷Callisto Monthly - August 2022 (FR)
      • 🇵🇭Callisto Monthly - August 2022 (PH)
    • Callisto Monthly - July 2022
      • 🇮🇹Callisto Monthly - July 2022 (ITA)
    • Callisto Monthly - June 2022
    • Callisto Monthly - May 2022
    • Callisto Monthly - April 2022
    • Callisto Monthly - March 2022
  • Technologies
    • 📈Callisto Dynamic Monetary Policy
      • Crypto-models To Overcome Inflation and Callisto Network's Approach
      • Skuld Hard Fork - Update On Progress
    • 🧊Cold Staking
      • Cold Staking And PoS Staking Comparison
    • 🪙Wrapped Callisto (ccCLO)
    • ®️DexNS 2021
    • ⛏️Proof of Work
      • ZPoW #1 - Exploiting The Block Time & Block Size
      • Callisto Network Introduces the Dynamic Gas Price
    • Ⓜ️Callisto Network Masternodes
    • 🎓Tutorials
      • Setting Up Metamask For Callisto Network
        • Update the RPC URL in MetaMask
      • How to buy Callisto with Your Credit Card
      • How to Run a Callisto Network Node?
      • Callisto Network Masternodes Set-up
    • 🌐Callisto Hub
    • 🧩Web 3.0 Infrastructure
    • 🔍Chain Inspector
  • We Fund You!
    • 💲We Fund You!
      • We Fund You Award - 1st Edition
  • Security Department
    • 🔍Auditing Department
      • Auditing Department Amendment v5
    • 📖Documentation
      • 🛡️Security Department Best Practices
      • 🪙ERC 223 Token Standard
        • ERC20 Standard Main Issue
      • 🖼️CallistoNFT Standard
        • Roadmap
      • ✖️Cross-Chain Bridges Security Model
    • Products & Services
      • 🔍Security Audits For Smart Contracts
        • Mission: Securing The Smart Contracts Ecosystem
        • Trust and Smart Contracts: Code is the Limit
    • 🤝Various Contributions
      • Ethereum Classic
        • ECIP-1092 51attack solution: PirlGuard & Callisto proposal
      • Ethereum
        • Statement regarding Geth v1.10.8 split
      • EOS
        • Page 1Chintai (EOS resource exchange) low severity issue.
        • EOS congestion 9/13/2019 and EOSPlay hack
      • Ultimate solution to 51% attacks: amend the Nakamoto consensus
  • Hack Investigation Dept.
    • Hack Investigation Department
    • Helio Exploit
    • Binance Bridge Hack
    • TempleDAO's STAX Contract Hack Investigation
    • NFT Theft Analysis
    • AUDIUS Governance System Exploit Overview
    • LUNA ‘Hardfork’ Review
  • One Earth, One Heart
    • 🌎One Earth, One Heart
    • 💚Callisto Charity Efforts
  • Community
    • 📥Callisto Network Improvement Proposals
    • 💬Callisto AMAs
      • Callisto Team's Ask Me Anything on 04/05/2023
      • Callisto Team's Ask Me Anything on 03/03/2023
      • Callisto Team's Welcome AMA on 10/11/2022
      • Callisto Team's Ask Me Anything on 10/10/2022
      • Callisto Security Team's Ask Me Anything on 02/09/2022
      • Callisto Team's Ask Me Anything on 28/07/2022
      • Dexaran's Ask Me Anything on 11/04/2022
    • 📌Get Started
  • Callisto Enterprise
    • 🪙Callisto Enterprise Token
      • Vision and Tokenomics
    • 👥Team
      • Callisto Team Motivation System
  • In The Press
    • 🟢Callisto Network
      • Ethereum, Ethereum Classic, Callisto Network, A Common History
      • Callisto Network: Three Years After Mainnet Launch
      • Czech Ethereum Killer
    • 🖼️NFTs
      • Artist Creates And Then Destroys Art To Launch CallistoNFT
      • Security Network Develops New NFT Standard To Address ERC-721 Flaws
  • Miscellaneous
    • 🧩Media Kit
Powered by GitBook
On this page
  • The statement of Callisto Network
  • The attack
  • Investigating the EVM exploit
  • Conclusion
  1. Security Department
  2. Various Contributions
  3. Ethereum

Statement regarding Geth v1.10.8 split

PreviousEthereumNextEOS

Last updated 2 years ago

On August 27, 2021 a chain split occurred on Ethereum mainnet (watch ). The accident was followed by describing that the issue was caused by the EthereumVM bug and other EVM-compatible chains may be at risk.

Original article by Dexaran posted on on September 2, 2021.

The statement of Callisto Network

The described accident was not a result of the EVM bug but a result of miscoordination in the client update. Ethereum developers introduced breaking changes in their Geth v1.10.8 release that affected consensus rules and these changes must have been implemented during the hardfork instead.

In fact, when you change consensus rules it is always possible that there will be “a fork” — those nodes who upgraded their code will stay in new consensus with each other and the ones that refused to update will fork off the chain and stay in consensus with other non-updated nodes (the best example is Ethereum — EthereumCLassic fork).

This is exactly what happened at Ethereum chain on August 27.

The attack

Here you can find a transaction that triggered the chain split on Ethereum mainnet:

As you can see the transaction created the contract.

The “exploit”: some nodes (Geth v1.10.8) thought that the code of a newly created contract must be 0x000000000000000000000000000000000000008e8bbbc599bf9ecb4756bb466edeba12fae3a49e00000000000000000000000000000000000000000000000000

while other nodes (older ones) thought that the code must be 0x0000000000000000000000008eae784e072e961f76948a785b62c9a950fb17ae62c9a950fb17ae00000000000000000000000000000000000000000000000000

They came to disagreement and splitted from one another.

Investigating the EVM exploit

Let’s analyze the “attack” to understand why this happened.

First let’s disassemble the input data of the transaction: 0x3034526020600760203460045afa602034343e604034f3

Here is the result:

  • [0] ADDRESS

  • [1] CALLVALUE

  • [2] MSTORE

  • [4] PUSH1 0x20

  • [6] PUSH1 0x07

  • [8] PUSH1 0x20

  • [9] CALLVALUE

  • [11] PUSH1 0x04

  • [12] GAS

  • [13] STATICCALL

  • [15] PUSH1 0x20

  • [16] CALLVALUE

  • [17] CALLVALUE

  • [18] RETURNDATACOPY

  • [20] PUSH1 0x40

  • [21] CALLVALUE

  • [22] RETURN

We can now read what the contract is actually doing:

  1. The contract is going to store the address of a newly created contract in the memory. For this matter it calls [0] ADDRESS [1] CALLVALUE and then [2] MSTORE opcodes where the first two are the inputs for the MSTORE. So the contract takes the address of a newly created contract and pushes it onto the stack. Then it pushes value 0 onto the stack (because no value is provided for CALLVALUE opcode. Then it takes the contract address from the stack and pushes it into the contract memory (the stack is cleared).

  2. [15] PUSH1 0x20 [16] CALLVALUE [17] CALLVALUE [18] RETURNDATACOPY these opcodes copy 32 bytes of ret into the memory (at this point “old nodes” and “new nodes” have it different already).

  3. [20] PUSH1 0x40 [21] CALLVALUE [22] RETURN these opcodes finish the execution returning 64 bytes of the memory i.e. make the returned 64 bytes of memory a new contract’s bytecode. At this point “old nodes” and “new nodes” disagree with each other how the code of the newly created contract must look like and therefore they can’t accept each others version of a block that includes the transaction of contract creation. This is the chain split.

It should be noted that this would not happen if nodes could agree on how the newly created contract’s code must look like. It doesn’t matter which version (shifted or unshifted) it would be — the point is that it has to be the same for all nodes.

Conclusion

Geth v1.10.8 release contains a bugfix for the EVM exploit. This bug could not cause a chain split on its own however. What caused the chain split was a rushed fix that changed consensus rules. Ethereum developers should have called it a HardFork, but not released as a regular client update.

There was a consensus at the chain how the instructions of the EVM must work. If you apply a change on consensus rules then you can’t pretend that it always worked like that. Instead there must be a specified block at which the consensus upgrade is considered applied and all nodes must follow it starting from this particular block number.

Next the contract is performing the [13] STATICCALL and here are the inputs: [4] PUSH1 0x20 [6] PUSH1 0x07 [8] PUSH1 0x20 [9] CALLVALUE [11] PUSH1 0x04 [12] GAS. You can find the description of what STATICCALL is actually doing . In this case STATICCALL should invoke the contract at address 0x04, it should provide all remaining GAS for this invocation, it should provide first 32 bytes of memory as input data (memory was filled at pt.1), it should take the result of the invocation and put 32 bytes into memory starting at byte 7. It is important to note here that the 0x04 address is a special target for this call — it’s a precompiled contract called “Identity Precompile”. It takes the data you provide it and the returns it back (can be used for some optimization reasons). You can read more about precompiled contracts .

Let’s dive into what is going on inside of the . Here the is a pointer to the contracts memory. It is and the returned value is the same pointer to the contracts memory. The important thing here is that the implementation of CALL, CALLCODE, STATICCALL and DELEGATECALL in Geth was changed on August 24, 2021 with . If we take a look at the previous implementation then we can find out that it was a bit different (watch ). Now “old nodes” think that the value of is a pointer to the contracts memory but the “new nodes” think it is the value.

At “old nodes” shifted the value of ret variable when trying to store this in memory (ret is a pointer to that exact memory) by 7 bytes.

🤝
here
here
STATICCALL in Geth
args variable
passed to the Identity Precompile
this commit
previous version of the instructions.go
ret variable
this line
the announcement
an article at Cointelegraph
Medium
https://etherscan.io/tx/0x1cb6fb36633d270edefc04d048145b4298e67b8aa82a9e5ec4aa1435dd770ce4