How your dapp can survive a gas price war

Recently on the Ethereum network there has been a big spike in gas prices, which is causing some pain for users since we had been enjoying very low prices for some time (well, since the great cryptokitty war of ‘17). I won’t go into the details of what has caused the increase in gas prices, but you can read more about it in this reddit post.

Because the types of dapps that can be built and how they should be structured depends at least in part on the gas price market, it is worth considering how gas price increases will affect your dapp.

Make sure each interaction provides as much value as possible

This is the most fundamental and important thing you can do. Especially if your dapp’s use case requires fairly quick transactions, you should ensure that there is enough “value-add” to justify using your service during price wars.

For exchanges like SportCrypt, this is possible because the fees paid in gas prices can be amortized to arbitrarily low percentages of the exchanged value.

As an example, in this transaction a user bet 5 ETH to win about 8.5 ETH on Switzerland-0.5 in the Switzerland vs. Sweden world cup match. That’s odds of +170 (american), 2.7 (decimal), or as we tend to think of it, shorting Sweden+0.5 at 63 (implied probability). To perform this transaction a gas price of 110 Gwei (!) was provided, and about 95k gas was burned, meaning about 0.01 ETH was spent on gas. It was probably necessary to expedite this transaction since the order was set to expire at kickoff in less than 10 minutes.

So, if this bet had won (it didn’t — huge Sweden upset), the user would have paid around 0.1% of their winnings in gas fees, even at such an absurd gas price. On SportCrypt there are no fees other than gas and the implied fee in the market spread, so this percentage directly decreases as bet-size increases (that’s what we mean by amortization). For instance, on our order-book right now you can bet up to 97.5 ETH (-185) on over 1.5 goals in tomorrow’s France-Uruguay game.

However, not all dapps will be able to arbitrarily scale their value-add so as to amortize away gas costs in this manner, which brings us to our next topic…

Off-chain actions

Anything that can be done on off-chain, should be. This can save your users substantial gas fees because actions which don’t require issuing transactions to the blockchain obviously don’t require any gas fees.

Naturally there are trade-offs with off-chain systems, usually involving centralization to some degree. However, many of the most successful dapps so far, such as EtherDelta and IDEX, have been hybrid on-chain/off-chain systems. Like these systems, SportCrypt uses a centralized off-chain order-book to improve interaction times and reduce gas costs. When trades are issued, they are settled on-chain by our smart contract.

In the example above, the market maker on the other side of the trade with 8.5 ETH at stake didn’t pay any gas whatsoever to perform this trade, and was free to wait until a convenient point in time when gas prices had subsided before issuing a claim transaction to collect the winnings.

Another important advantage of an off-chain order-book is that market makers can — at no cost — provide liquidity on obscure games, even if nobody ever wants to trade with them.

Optimize contract code

Although you as a developer don’t have control over the gas prices set by your users, or the gas market conditions that influence those prices, you do control how much gas is burned by your contract on each interaction.

Generally the most effective way to optimize a program, smart contract or otherwise, is to keep it simple. There are obviously exceptions to this rule, such as using more complex algorithms for certain tasks, but, to a first approximation simple means efficient. And on the EVM, efficient means inexpensive.

Once you have designed, implemented, and thoroughly tested (right?) your simple system, you can begin to consider optimizing it.

Although there are some IDEs for solidity/EVM, I tend to just use thesolc binary to dump assembly so I can see how it is compiled:

$ solc --asm --optimize MyContract.sol

With a copy of the EVM operation gas costs handy, I’ll got through this output and check that everything looks sensible.

Keep in mind that the solc optimizer isn’t nearly as sophisticated as compilers such as gcc . One fairly simple improvement that can save a fair amount is instead of accessing the same storage location multiple times, load it once, save it on the stack or in memory, and access that copy every time instead of the storage. Many cases where you might assume a compiler would do common sub-expression elimination, solc will not.

It goes without saying you should minimize the frequency of storage writes as well.

After you’ve gotten rid of the low-hanging fruit, there are many micro-optimizations that you can try too. For example, consider this loop:

unit i = 10;
while (i > 0) {
i--;
}

This version is in fact slightly more efficient:

uint i = 10;
while (i != 0) {
i--;
}

One might think that solc would notice there are no negative uint values and make them equivalent, but it doesn’t, at least not yet.

An event called the Solidity Gas Golfing Contest was recently held where contestants competed to see who could best optimize programs for some basic tasks. I am looking forward to reading analyses of the submissions and examining them myself.

One final note about optimization: Be careful not to overdo it. Excessively complicating your system in the name of efficiency can result in costly bugs, such as the parity multi-sig wallet incidents.

User interface

You can’t optimize gas usage down to nothing, and you can’t do much about day-to-day gas prices, so you should try to work gas prices into your UI at a fundamental level.

Since users will have different gas price tolerances, and various interactions might be of differing urgency, at SportCrypt we feel that it is not enough to rely on the default prices provided by metamask/infura.

We provide an item in the settings tab where you can change your default gas price. By default the price suggested for your transaction is the “Standard” price from ethgasstation.info, though of course users can change this in the metamask dialog.

Gas price settings

When high-speed transactions are essential, such as trading while a game is being played, you might select “Fastest”. Whereas when you’re hedging out some exposure on tomorrow night’s games, “Safe Low” might be adequate.

Because gas prices can have such a significant effect on the user experience, we also have a display of the current gas price in the top-right corner of our app:

Current gas price display

The picture doesn’t do it justice, but basically it flashes red or green when the price increases or decreases so that it’s highly apparent from the trading interface.

Keep calm and dapp on

Even if you do everything described above, your dapp might still be too expensive to use during a gas price war. Remember that previously prices have in time subsided to manageable levels, so you can probably ride it out. Also, there may eventually be technological advances that alter the value-add vs gas equations and hopefully won’t require drastic modifications to your dapps.