3 Ways to Counter the Frontrunning Vulnerability in Smart Contract Development

Daniel Chakraborty
Lumos Labs
Published in
7 min readJan 19, 2023

Even if queues at the supermarket or at the outlets where you pay your utility bills are history, some of us know what it feels like when someone jumps in line.

To the front of the queue, that is. Particularly, if it is for the reason that their bill is far more in value compared to the others standing in line. Clearly, this should not be a criterion when it comes to the promptness of service.

Now, this business of being moved to the front of the line occurs in Ethereum smart contracts too. Otherwise known as the frontrunning error, whose name has been obtained from a similar phenomenon of the stock market, smart contract transactions that pay higher gas fees tend to be favoured more than those that do not.

Breaking Down the Front-running Vulnerability

Right off the bat, this vulnerability does not occur due to faulty programming but makes use of the way transactions are ordered and added to a block from the ‘mempool’.

Where to Find and Buy Bitcoin — Geeks for Geeks

Apart from regular users looking to make a quick buck, miners tend to gain from such a transaction and which is why they are the ones who are most likely to watch for such transactions before they get added to a block. In fact, once they do, they send a transaction of their own for an unfair financial reward, which ends up getting added to a block rather than the one that was sent first.

What one must keep in mind here is that transactions that have been committed with a higher gas price tend to get processed first compared to others. Keeping this preference in mind, the attacker can change the outcome of events like auctions, trading or initial coin offerings in their favour simply by paying higher gas fees.

Let’s look at this common example to understand how the frontrunning vulnerability works:

In this example, we have three actors: Naman, Kaavya and Aishwarya. Naman first deploys the Hashing challenge as a smart contract for the other two to solve. Whoever solves this hashing puzzle will obtain 10 ether as a reward.

Now, Kaavya finds the hashing solution first and sends it with 10 Gwei as gas fees, from her own smart contract:

On the other hand, Aishwarya finds the answer a little later and passes the correct answer to her smart contract with 100 Gwei as gas fees.

Because of paying higher gas fees, instead of Kaavya receiving the 10 Ether reward, Aishwarya receives it, as shown below:

Simply put, this is the frontrunning or the transaction-ordering error, as it processes transactions based on the value of the gas fee.

In other words, even if Kaavya submitted her answer ahead of Aishwarya, she gets nothing for her efforts, as shown below:

Since this ‘jump in line’ by Aishwarya won’t sit well with Kaavya or anyone else, a few preventative measures must be considered for our smart contract code.

3 Ways to Deal with the Frontrunning Vulnerability

Now, there are fixes that can prevent such a loss. In other words, we should be able to lock one transaction in as the one that should receive the 10 Ether.

Method 1: Transaction Counter
Using a transaction counter is one of the simplest ways to deter anyone else from getting the reward by any other means.

As you can tell from the code added below, a transaction counter has been added which locks in the transaction committed by the person who has completed the hashing challenge first. Since only the first one to do so must obtain the reward, we inform all participants to add the value 0 along with their solution.

Since the current value of txCounter will be zero for the first presented solution, it gets locked in. In other words, and as in the example above, Kaavya will enter her solution as well as the value of zero to receive her reward of 10 Ether.

If anyone else does this, the solution will not be accepted since the transaction counter has been incremented to a value greater than one. By that time, the entire 10 Ether reward, which should go to Kaavya, will be transferred rightly to her.

Method 2: Setting Gas limits
Now, with this method, the focus is on setting a gas limit for all transactions. Both, a lower and an upper limit, if necessary.

As you might recall, transactions are ordered based on how much gas fees have been paid for said transaction. While this might not fully eliminate that ordering, this certainly does reduce it to a great extent.

If you look at the code below, all transactions that pay gas amounting to 1 or less will go through but those who try to jump the line by paying more gas will not, thanks to the gasThrottle modifier. In this case, 1 Wei or Gwei might be the standard cost of processing such a transaction and which is all that will be permitted.

So, if all transactions do not vary all that much in gas by virtue of this throttle, the issue of showing preference to certain transactions will not arise. While there are advantages to such an approach, the gas fee paid is bound to change in the future.

What is high today will be low in a couple of years, so Naman has to be watchful of this at all times. Or else, Aish might be able to take advantage of these changing values by just waiting for a while.

Method 3: The Submarine-Send Approach
Now, while the prior two approaches might work for simpler situations, they never really address the root cause of the front-running vulnerability: full disclosure of transaction information to both miners and other malicious users.

It should be obvious that for as long as these two parties have access to the information of each transaction, the chance of gaming the system persists. Clearly, a method by which this time-sensitive information must be hidden is necessary and which brings us to the submarine-send approach, implemented as part of the LibSubmarine smart contract library.

4 Steps in the submarine-send approach — thegostep blog

When one uses this approach, they hide the transaction information in such a way that miners or regular users cannot really take advantage. Encryption plays a big role in protecting this information, which, based on the owner’s discretion, can be revealed once it is added to a block.

That said, even if this approach isn’t perfect, the level of protection that it offers is far better compared to the other methods, because of its willingness to address the real reason why front-running takes place — both in the real world and on the blockchain.

Other Strategies to Sidestep the Frontrunning Vulnerability

Of course, the strategies discussed in the previous section aren’t the only ones that protect smart contracts from the ‘front-running’ vulnerability.

With side chains, the ordering takes place off-chain while the settlement does on it. With these two steps taking place on different platforms, this not only has benefits for increased throughput but will deter miners or regular users from obtaining the information necessary to exploit the frontrunning vulnerability.

The Sidechain in Blockchain Tech — Digitalogy

Another strategy, even if theoretical in nature, involves randomizing the order of transactions for a particular round that has been committed in a commit-reveal scheme. This is enforced using smart contract logic. Frontrunners will not get to the front of the line with this approach because the ordering is determined by the aforementioned smart contract.

Finally, another approach involves the implementation of the Injective Protocol where users solve verifiable delay functions for that all-important t-value that determines who gets the order. As a result, by being able to move away from the random ordering system that most blockchains use, the possibility of frontrunning attacks is reduced as well.

That said, if you’d also like to keep in touch with the latest updates in Web3 development as part of a growing community, you can join our Metaverse Discord Server below.

--

--

Daniel Chakraborty
Lumos Labs

Loves emerging tech, languages such as Python, JavaScript, Solidity & Haskell. Writes about Web3. Works at Lumos Labs.