Ensure the security of your smart contracts

MEV: DeFi Transaction Ordering for Profit and Fun

Author: MixBytes team
This article is about one of the new, serious challenges for DeFi projects, which in the previous financial reality worries only a small number of very narrow specialists who have restricted priority access to exchange servers. In DeFi, any user has access to the financial APIs. On traditional exchanges, these are high-speed communication lines, privileged access for a lot of money, and specialized software. In DeFi, access is algorithmically the same for anyone with at least 1 wei, the API specification is completely open and everything is free to use. So now, in the blockchain world, the same transactions ordering issues apply to all users, and a huge number of possible types of financial instruments in the form of smart contracts provide many opportunities for exploitation of profit opportunities at different levels.

Currently the volume of transactions in Ethereum every day is measured in billions of dollars, and the competition for a position in the block has grown up to enormous values. In "gas auctions" you can find transactions where commissions are measured in tens of thousands of dollars, and the number of automated trading funds is increasing every day.

Something interesting lies here, I suggest having a closer look at this issue...
Introduction
The problems with transactions ordering discussed in this article fully demonstrate the "dark forest" concept - this term was voiced in the book by Liu Cixin "The Three-Body Problem" which I sincerely admire and which is very accurately mentioned in an excellent article ("Ethereum is a Dark Forest ") that inspired me to write this text. In this book, the main idea is that we do not see millions of developed civilizations in the Universe, not because they do not exist, but because as soon as a civilization reveals its existence, it is instantly destroyed by more developed ones. In the "dark forest" it is enough to scream once or turn on the flashlight and terrible monsters will instantly devour the defenseless wanderer.

Blockchain networks have shown many times that if something can potentially be exploited for profit, it will happen sooner or later. This is exactly what happened with transactions ordering on the Ethereum network, where any "lit up" opportunity to make a profit is instantly used by a variety of players with larger financial and infrastructural resources. Let's talk about this ...

The article requires the reader to understand the functioning of the Ethereum network and smart contracts.
Front-running and MEV
Let's imagine such a simple piece of Solidity code (and you definitely shouldn't make anything alike):

pragma solidity >=0.7.0 <0.9.0;
contract Test {
    bytes32 private hash_of_secret;
    constructor (bytes32 _hash_of_secret) {
        hash_of_secret = _hash_of_secret;
    }
    receive() external payable {
        // this function receives ETH
        // to the contract balance
    }
 
    function claim_eth_by_secret(bytes memory secret) public {
         // Provided that a preimage of
         // a previously saved hash is sent
         // it sends the entire balance to the sender
         // of the transaction and destroys the contract.
         require (keccak256(secret) == hash_of_secret);
         selfdestruct(payable(address(msg.sender)));
    }
}

When a contract is deployed, it will store the hash of the secret line known only by the contract creator. After such a contract is deployed, one can send any amount of ETH to it, which will be accumulated on the balance and after the secret (the preimage of the saved hash) is sent, all ether on the balance will be sent to the initiator of the transaction and then the contract will be destroyed. A kind of "piggy bank" with a secret.

In Ethereum, if you are not a mining pool, there is practically no chance of getting this ether. Even with a pool that chooses how to form a block itself, algorithmically, there is an opportunity for more powerful participants to "beat up" the block, if the reward is worth it. This is what happens:
  • the transaction containing the secret will be published in mempool and distributed throughout the network via the p2p network

  • the transaction will be analyzed by the autoanalyzer which will determine "is it possible to perform exactly the same transaction but from my own address and get a profit?". For our transaction, the answer is yes. The "secret" is now known and anyone who sent it before us will receive ether from the contract

  • without access to the mining pool, the attacker can simply charge a large commission ensuring that his transaction will be published first

  • having direct access to mining pools, the attacker is guaranteed to place it higher in the block than ours
Despite the simplicity of verification in the example, you can easily imagine in its place any proof that allows one "lucky" address to receive ether (i.e.: "every hundredth transaction is a winning one" or "the last participant closes the contract and receives a reward for this operation").

It turns out that as soon as a transaction appears on the network by completing which you can get a profit, it is immediately "swept up" and these ideas have been wandering around for a long time. Some time ago I even wrote an article "Ether janitors" about bots that exploit taking away any tokens or ether found on "weak" addresses instantly.

After the appearance of DeFi and arbitrage such opportunities have increased by orders of magnitude, since profit is gained with beneficial trading operations in DeFi as well. And the more sophisticated the financial instruments are and the more complex arbitrage is, the more opportunities exist for front-running. Let's consider a more realistic example: arbitrage on two decentralized exchanges.

For example, an arbitrage bot saw that the rates of some SHITCOIN are very different on DEX1 and DEX2 and wants to swap on two DEX-es at once taking a flash loan of 100ETH for a small commission (it will allow you to make an exchange for a larger amount and get a larger profit). A special contract previously deployed by the bot is used for such operations. It accepts a bunch of operations from the bot, and performs them all in one transaction, like this:

function perform_trade(bytes[] operations) {
    // operations contain serialized
    // calls to several DEXs,
    // swaps, flash loans, etc., for example:
    // 1. get a flash loan of 100 ETH
    // 2. swap 100 ETH for 100k SHITCOINS for DEX1
    // 3. swap 100k SHITCOINS for 120 ETH for DEX2
    // 4. check the slippage (that 120 ETH> 100 ETH)
    // 5.return the flash loan of 100 ETH (profit: 20 ETH)
    // 6. transfer the remaining 20 ETH to the bot address
}
Clause 4 is especially important ("slippage" in terms of stock trading). In such a way the trader is insured against the fact that while the transaction is completed, the price suddenly changes and it will not be possible to get a profit. If this check fails, the entire transaction is rolled back.

After operations 2 and 3 are performed, the SHITCOIN rate on DEX1 will increase and on DEX2 it will decrease, because swap pools in DeFi when buying one of the tokens algorithmically increase its price and when selling they decrease it. The price difference between the two pools will decrease and the possible earnings from arbitrage will also decrease (or disappear altogether). Therefore, if someone performs a similar transaction earlier (possibly with different amounts), then subsequent operations will be performed at a different price and may fail the slippage check. While without using slippage, there is even a possibility of losing funds on a trade if prices are rebalanced in the opposite direction.

The more advanced the transaction analyzer is, the more potentially profitable transactions it can detect. To use the "profit opportunity" that appears, you can simply repeat the same operation (literally copying the bytecode of the calls), but replacing the addresses and signatures with your own ones. And, the more likely it is to place your transaction higher than the desired one, the more likely it is to take profit from the transaction for yourself.

On one hand, this software "steals" "profit opportunities" from traders, and on the other hand, it is simply the development of arbitrage - thus another "layer" appears in DeFi on which arbitrageurs can bargain for transactions ordering. The main beneficiaries are, of course, miners - for them this is a completely new market and earnings, parallel to mining, sometimes bringing in a huge income.

Due to such activity on the market, the term MEV appeared. It stands for "Miner Extractable Value" or, if more general mechanisms are considered, "Maximum Extractable Value". This number means the amount of funds that can be obtained by manipulating the order of transactions in blocks. In other words, this is the profit that a block miner can get if he makes the most of his ability to reorder transactions.

When reordering transactions, you can act in several ways: bad, fair to middling, and good (in relation to the user who posted the transaction). Let's imagine the situation in txpool when preparing the block was first like this:

[block begins] 
...previous transactions...
tx_orig: profit = 10 ETH, slippage = 3%, gasprice = 20Gwei, result=Success
...next transactions...
[block ends]
, then:
Option 1: destructive front run

[block begins] 
...previous transactions…
tx_mev: profit = 10 ETH, slippage = 3%, gasprice = 20Gwei, result=Success
tx_orig: profit = 0 ETH, slippage = 3%, gasprice = 20Gwei, result=Failure
…next transactions...
[block ends]
The user wanted to execute a transaction with a slippage of 3%, and if this condition is not met, the transaction falls. The front-runner made the same transaction, placing his transaction higher. This can be done by setting a higher gas price, and thus front-running transactions in Ethereum without access to the miners' machines. But an attentive reader will see that the gas price has not changed in our example. Why then a later generated transaction was put in the block above the original one? This is done on purpose in order to show that the miner can change the order of transactions on his own, regardless of the transaction prices, if the income from such transactions is higher than usual miners' rewards.

This approach is called destructive because the user was hurt and his transaction was rolled back (although he paid the commission). This strongly demotivates market makers, so the community is actively looking for ways to combat destructive MEV. But more on that later ...
Option 2: cooperative front run

[block begins] 
...previous transactions…
tx_mev: profit = 5 ETH, slippage = 3%, gasprice = 20Gwei, result=Success
tx_orig: profit = 5 ETH, slippage = 3%, gasprice = 20Gwei, result=Success
…next transactions...
[block ends]
In this case, the user's transaction was completed. The user did not earn the planned 10 ETH, but still managed to execute his transaction within slippage, having received 5 ETH. The other part of the profit (5ETH) went to the front-runner who selected the parameters of his transaction so as not to "break" the trade operation for the "next" one. For example, he operated with small amounts of tokens just enough in order not to break the slippage criteria for the next transaction. This is a "fair to middling" approach which is much better for the user than the previous option. By using destructive MEV, miners risk being left on the market without active market makers that will harm everyone indiscriminately. That is why the cooperative MEV option seems more preferable for all of us in the long term.
Option 3: back run

[block begins] 
...previous transactions…
tx_orig: profit = 10 ETH, slippage = 3%, gasprice = 20Gwei, result=Success
tx_mev: profit = 1 ETH, slippage = 3%, gasprice = 20Gwei, result=Success
…next transactions...
[block ends]
In this case, the user executed his transaction and made a profit but after his transaction was emulated, it turned out that it was possible to "pick up the crumbs". For example, the user did not have the required amount in order to equalize the prices in the two pools to 100% and after his transaction there was still an opportunity to repeat the same operation with a guaranteed profit. This is the best method of all since it has no effect on the user's transaction, everyone is happy. In this case, MEV acts as a "booster" of arbitration in the network.

In other articles, the types of ordering exploitation are different - someone singles out "sandwiches", someone does not distinguish between cooperative and destructive approaches, but all of these are exploitations of transaction ordering. I only gave some illustrative examples.
Anti-MEV
Everyone wants to fight MEV. Traders resent the theft of new "profit opportunities" and the profits taken away. Users are offended for the transactions that are taken away from them, if they have not made provisions in the contract code to issue rewards to specified addresses. Many miners understand that too much of MEV will drive users out of DeFi leading to losses in fees. Not the last place is taken by the exploitation of users' errors - if a user, for example, accidentally entered an amount with an extra zero and a front-runner instantly used it to gain profit, depriving the user of even the slightest opportunity to correct the error.

In a centralized world, front-running is "banned by the SEC" and everyone is strenuously pretending it doesn't exist — you're unlikely to google anything about this. At the same time brokers can easily profit from clients' trades by informing a friend in any way before a trade and it is just unreal to detect such front-running in centralized systems. In the blockchain industry, laws do not work in words and the only working way is algorithms and economic mechanisms that make honest behavior profitable. It is beneficial for miners to engage in transaction ordering as long as there are sufficient financial incentives. If there are mechanisms that make it easier and more reliable to get comparable income, it will work - for example, direct payments from traders for a guaranteed position of a transaction in a block, increased income from gas auctions, cooperative MEV, etc.

It is these ideas that are embedded in projects assigned to solve MEV problems and ensure fair transaction ordering. The most significant steps in this direction are being made as part of the Flashbots project, on their GitHub you may find a lot of useful materials, analytics on MEV transactions, a modified Geth client that allows miners to accept pre-built bundles of transactions, for the use of which they receive additional rewards and much other.

The idea behind Flashbots is as follows - instead of engaging in MEV, miners are offered to receive guaranteed additional income through direct payments from traders and transactions are ordered on separate services - relays where traders trade for the order of transactions without seeing other transactions, using direct payments to the miner (bribes) besides gas price. After the end of trading, transactions are packed into a single bundle, which the miner must include in the block as early as possible, without changing the order of any transaction. A very important requirement is that transactions in a bundle should not revert, which means that a trader will not waste money on commissions for broken transactions when he could not win an ordering auction - because of these commissions, novice algorithmic traders suffer a lot.
Dark-dark Forest
Greedy miners, smart hackers, cunning algorithmic traders, all these ordering monsters in DeFI are terrible. They will devour everything and will not allow anyone to live in peace in the world of decentralized finance. Is it really so terrible and there is no hope? Of course, there is! When describing methods of dealing with destructive MEV, it is often forgotten that these are just algorithms that must react quickly and predictably to certain conditions, which means they can also be attacked in the opposite direction. So beware, beasts, even more terrible guys can go on a hunt and not every glowing flashlight in a dark forest is a victim!
Any algorithmically predictable behavior in finance is a vulnerability that can be exploited. Knowing that front-runners will act in the same way on a certain stimulus, you can deceive them. One illustrative example is the salmonella project. This technique which the author quite aptly called the "poisonous token" can be used for other attacks on DeFi algorithms. The main idea is to create a token, the operations on which work differently depending on who is calling its functions. The transfer() function is "poisoned" in Salmonella:

// ...
  if (sender == ownerA || sender == ownerB) {
    _balances[sender] = senderBalance - amount;
    _balances[recipient] += amount;
  } else {
    _balances[sender] = senderBalance - amount;
    uint256 trapAmount = (amount * 10) / 100;
    _balances[recipient] += trapAmount;
  }
  emit Transfer(sender, recipient, amount); // !!! amount !!!
// ...
In other words, the token works correctly only with the author's addresses when for everyone else it transfers only 10% of the tokens to the recipient's balance while emitting an event with the correct amount. The MEV analyzer considered transactions with this token to be profitable because it relied on data from events (this is much more convenient than reading balances). Then swap pools were created with this token in Uniswap and on other projects and balanced so as to create a "profit opportunity" for the MEV analyzer. As a result, the author's transactions triggered a reaction from the MEV front-runner who left large amounts of ETH in the pool which were taken by the attacker. Decent earnings for the whitehat hacker.

Of course, front-runners will improve their analyzers and try to deal with such attacks but algorithms in DeFi are developing and tokens and DEXs are only the first examples because there is still a huge NFT sector where financial transactions are also carried out and there is also room for MEV.

Each new complication in logic opens up new opportunities to exploit vulnerabilities on both sides - so we will see a constant battle of "shell and armor" as it happens in any technology industry. Unlike the centralized world of exchanges, there are no privileged parties, intermediaries, and paper mechanisms. It means there are no restrictions and any attacker can be attacked at any time. Each new attack in DeFi is public and gives rise to more and more protection methods, such as Flashbots, privacy-preserving algorithms, reputation systems, etc. - so it's not all that bad.
Conclusion
Even from a moral point of view, all of the abovementioned cannot be accurately qualified as hacking or legitimate activities because we cannot dictate to miners in what order to include transactions in a block and we cannot prevent the program from analyzing transactions in the p2p network and sending our own. Laws will not help here and any pursuit of attackers using traditional methods will be difficult, ineffective and will only slow down the development of countermeasure algorithms, because attacks cannot be hidden here, they are studied by a large number of hackers around the world and they not only attack but also protect.

If you consider all of the above to be terrible insurmountable problems and hacker manipulations, you probably shouldn't go into DeFi - go to the bank and put your money on a deposit. If you do not take into account the risks of breaking protocols or unexpected departure of the anonymous project team - go to the bank. If you think that the promises of centralized exchanges and banks are safer than open sourced, publicly audited code - go to the bank, you have nothing to do in DeFi. Only here are a few final contentions.

Nowhere is code security more serious than in DeFi. In the conditions in which DeFi works, it cannot be otherwise. It is a completely open environment where there are no trusted parties, where it is impossible to hide even a bit of information. Many hacks in DeFi? This is natural - attackers have huge advantages - they see 100% of the code and can simulate any attack with great accuracy but it is impossible to stop them. An attacker only needs to find one vulnerability while developers and auditors need to foresee everything. Any bad code is immediately attacked, any error is fatal. Truly - "code is the law".

But at the same time, only in the conditions of the "dark forest" truly stable financial protocols will be born. Here they will undergo a brutal natural selection without cheating help in the form of "SEC banned", "the exchange promptly shut down", "the press release briefly mentioned ... ". Alas, few will survive among the DeFi mechanisms but the survivors will definitely deserve to operate with finances in the age of information technology.
Disclaimer
The information contained in this Website is for educational and informational purposes only and shall not be understood or construed as financial or investment advice.
Other posts