Hello, everyone! Sorry for the long post, but I think you will all enjoy it and hopefully learn somethings along the way. Here's an image of my Excel calculation results and here's an example contract with another set of numbers. Both files will be helpful later on (you'll see) but aren't necessary to understand this post. TL;DR: An attacker or competing chain could disrupt Ethereum for significant periods by taking advantage of miner's greed, and the best way to prevent it is to reenable dynamic gas limits.
Intro
With the recent congestion issues on the Ethereum network, it has become obvious that there is a serious issue with the current gas payment structure. Not only does the issue pose serious questions about the scalability of Ethereum, it also opens the network up to attacks. I’ll show how a relatively small sum of Ether can be enough to kickstart a miner-enabled DDoS attack. But first we have to understand the problem, and to do that we have to realize where it came from.
Origin of the Problem
Gas, for those that are unfamiliar with the inner workings of Ethereum, is a unit of computation power used to measure the processing requirements of a transaction. A block’s gas limit is the max amount of processing that needs to be done to complete all transactions in the block. Normally, the gas limit would rise and fall with the needs of the network, allowing blocks to expand as the transaction volume increased.
When users need to get their transactions into a block faster, they set a higher gas price. The gas price is the ratio of gas used to the amount of ether paid to the miner as a processing fee (to account for fluctuating values of Ether). Miners ideally try to include as many transactions in a block as they can and prioritize the transactions with the highest gas prices in order to collect as many fees as possible per block. This is where the system breaks.
Some time ago, there was an attack on the Ethereum network involving contracts that would use all the gas in a block on processes that had extremely slow execution speeds, resulting in long block verification times. In order to combat these contracts, miners collectively lowered the gas limits of each block. The default gas limit on new releases of mining software became a fixed value, so the network no longer expanded blocks as they became more filled. The decision reduced the effects of the malicious contracts, but created the situation we are in today.
Recent Developments
Recent ICOs (Initial Coin Offerings, like when a stock goes public but for cryptocurrencies) required that entrants purchase the coins within a certain window of time. This created a race condition: Only transactions processed in that window would be valid purchases, regardless of when they were first sent to a miner for processing. The constant gas limit imposed by the miners meant that there were a limited amount of transactions that could make it into the window. So, entrants increased the gas price of their transactions so they would be processed before the rest. As more people tried to send transactions, the necessary gas price to stay in the window began to skyrocket. Some people paid thousands of dollars in transaction fees to be included in the ICO. If their transactions were too late, they simply wasted their money. The problem wasn’t confined to just the ICO, either.
Since everyone was paying extra to get into the ICO, regular transactions were postponed until they were the most profitable. This meant that any smart contract actions not related to the ICO were put on hold until the congestion cleared, which effectively froze the smart contracts for the duration of the ICO.
While a smart contract delay of several minutes might be inconsequential, a similar network disruption for an entire day (or several) would cripple any business that relied on Ethereum smart contracts for its daily activities (such as with ERP or logistics applications). This has huge implications for the future of Ethereum, since businesses will look to more reliable blockchains or switch to their own, off-chain solution if Ethereum can’t scale to their needs.
Creating Problems to Highlight Problems
Anyone that thinks that these conditions are a fluke is mistaken. The situation has been manipulated by the miners to profit off the limited transaction volume and increased gas prices. You see, it's actually profitable for miners to create these situations: if everyone could fit into the window, they would not need to pay exorbitant gas prices. The longer they keep the gas limits down, the more people are willing to pay to get into these ICO’s. It’s not just enough to change the way we do ICOs: We have to change the conditions that led to this current situation. Until then, an attacker can abuse the current conditions to destroy Ethereum from within. And here’s how:
Creating Our Attack Contract
(Here's where that example contract will be handy) To create our attack, we first start with a simple derivative coin sale contract. We’ll call these DDoS Coins, or DCoins. At the end of the sale, all the DCoins will be converted back into Ether at the rate TotalEtherCollected/TotalCoinsMade.
1) We seed the contract with a starting amount of Ether. This amount will determine the price of entry per generation (higher seed amount means higher prices and incentive to enter).
2) We require that only transactions with less than a certain gas price are allowed to purchase coins, preventing people from spending more gas to get into the sale early.
3) We create a set of ‘generations’ with varying conditions on the sale, where the current generation is determined by the total number of successful purchases. The earlier generations have more favorable terms than later generations.
4) We also require that each transaction in a generation receives the same amount of DCoins regardless of how much Ether is sent with it (as long as it is above the generation’s price).
5) In order to incentivize miners to process the transactions, a percentage of the total Ether in the transaction goes to the block’s coinbase (the miner that mined the block).
6) After a requisite number of generations have passed, the DCoins can be redeemed.
So what does this attack do? First, the seed Ether creates an incentive to buy DCoins. Since each coin is worth (SumOfPayments+SeedEther)/(NumberOfCoins), it will always be profitable to enter into the contract. Because the early generations have more favorable conditions, it will be most profitable to enter the contract earlier. We limited the gasprice, so the only way to incentivize a miner to process a transaction earlier than any other is to include a higher amount of Ether in the purchase transaction (and therefore send a higher amount to the miner when their percentage is taken out). Additional Ether over the generation’s price that is not sent to the miners is stored in the contract, increasing the value of the contract (and subsequent coins). As the generations pass, the contract stores more and more Ether, becoming profitable to enter even in the later generations.
Since it’s at least profitable to enter the contract, it can be expected that all coins will be purchased as they become available. The point of the contract is now to get as many transactions in as early as possible. This creates the same race condition as the ICO mentioned before, and results in the network becoming increasingly congested as more transactions try to be included in the latest block. With enough seed Ether, it is possible to run iterations on this contract indefinitely and effectively DoS the network. How much seed Ether would be enough? According to initial calculations (see spreadsheet results), it would only take around $1M in seed Ether to create enough demand to fill every block on the Ethereum network (at current limits) for two whole days. Which means that it would only cost $3.5M to shut the network down for an entire week. To put that in perspective, Poloniex has daily transaction volumes of over $25M in Ether alone, and nearly twice that in Bitcoin. The capabilities are there, and it is only a matter of time before a competing chain implements this contract on Ethereum to drive the value of the network into the ground. And this is with a basic smart contract that was coded in a day, not a sophisticated or mathematically optimal exploit.
Conclusion
So, what is the solution to the problem? Simple: Miners need to dynamically increase block gas limits again. Easier said than done, unfortunately. There are enough reasons for miners to keep the limits low that we may never see 100% consensus on an algorithm without another fork. Other methods are likely in the works, but until there is a concrete change, the Ethereum network will be vulnerable to attacks thanks to the greed of its own miners.
Want to add to the discussion?
Post a comment!