0

If instead of using my wallet I use a contract in Solidity to make the swaps in Uniswap (That is, calling the uniswap API from the contract instead of using the Uniswap interface)

Is it possible to avoid front-running in this way?

Is there a way to obfuscate the transaction using a contract so that it is not seen by the front runers?

Or could the approach be to do two transactions together (in the same transaction) to avoid the front-run?

5
  • No. Every single transaction must come from a user address. Would you be able to send money from your bank to someone/somewhere without telling who you are ? Sep 7, 2021 at 9:56
  • Contract has an address. Contracts can send transactions... Sep 8, 2021 at 14:19
  • But a contract can never generate a transaction without a user adress intervention... Sep 8, 2021 at 14:41
  • My wallet->My contract (1,2,3 tx) -> Uniswap router Sep 8, 2021 at 15:08
  • Well. That surely goes against blockchain concept and should not exists... Sep 9, 2021 at 6:04

2 Answers 2

1

There are two parts in Uniswap: the centralized frontend (website) and decentralized trading contracts. Most(?) users utilize the frontend to trade, but it's perfectly ok to also use the contracts directly.

What frontrunners do, is that they monitor and analyze the mempool for transactions. So they monitor transactions which are pending, but not yet processed. If they notice a transaction which profits from some trade, they try to frontrun it with their own similar transaction - by sending a direct transaction to the Uniswap contracts.

Therefore it's not possible to prevent frontrunning by simply utilizing the contracts directly.

Furthemore, you can't really do two transactions in one transaction. If you utilize a contract which performs operations on multiple contracts, you can achieve multiple internal transactions within one transaction. Unfortunately that probably won't help you in obfuscating the trade - frontrunners will simply emulate what the transaction does and analyze whether it would give them profits.

4
  • I mean within my contract, in a transaction to make several transactions. Perhaps a buy and several small sells (0.1%) in the same transaction and of course with my contract, without code verification. Is there really no documentation or anyone who has tried to do this? Perhaps using some type of condition in the sell and if it is not fulfilled rollback the buy. Sep 8, 2021 at 14:28
  • You can try to obfuscate the logic (and not publish the source code), but the frontrunners can still execute (and emulate) the contract. And therefore they can see the status before and after the transaction. Sep 8, 2021 at 14:32
  • If it were possible in Solidity to get the previous transactions from the current block, the front run could be avoided. Because if I detect that in the same block someone has made a swap with the same token that me, it will surely be a front run and I can stop the transaction. Is it possible in solidity to get the previous transactions of the current block? Sep 8, 2021 at 17:48
  • Please post a new question if you have new questions. Sep 9, 2021 at 5:09
1

From here

The Uniswap transactions can be front run to certain extend. Since miners, who build blocks, can decide the order of transactions in the block they are building. They could add swap transactions before yours (front running) to make a profit.

In order to minimize the front running issue, Uniswap introduced amountOutMin and deadline arguments to the swap methods, so that if there are front running transactions or race condition that caused the output amount token to be less than the specified amountOutMin, then the transaction would revert, and no token is transferred. In addition to that, if the transaction is included in a block after the specified deadline block, then the transaction would also revert.

Github UniswapV2Router02.sol

 function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual override ensure(deadline) returns (uint[] memory amounts) {
        amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT');
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, to);
    }

ensure is a modifier function

modifier ensure(uint deadline) {
        require(deadline >= block.timestamp, 'UniswapV2Router: EXPIRED');
        _;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.