Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Brock/flashloan arb mevshare #439

Merged
merged 21 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Automated Arbitrage Bot

With the flash-loan arbitrage smart contract finished, our last task is to automate the process of finding and back-running other users' trades.

To reiterate our goal, the idea is to find pending transactions from other Ethereum users and backrun them (send our transaction immediately after the user's transaction). If the user's trade moves the price enough, we'll arbitrage the trading pair between two exchanges for a profit.

## Finding Pending Transactions

When a new transaction is received, it's broadcast to searchers via [Event Stream](/flashbots-mev-share/searchers/event-stream). Each transaction shares varying amounts of data via [hints](#/), but by default, transactions that trade on Uniswap, Balancer, or Curve will expose the trading pair's contract address in the log topics.
zeroXbrock marked this conversation as resolved.
Show resolved Hide resolved

Here's an example of an event from a transaction with MEV-Share's default privacy settings:

```json
TODO: ADD EXAMPLE EVENT
```

If we look up the address specified in the log topics, we'll see that it's a trading pair contract for INSERT_TRADING_PAIR_HERE on INSERT_EXCHANGE_PROTOCOL_HERE. This tells us that the user has either bought or sold INSERT_ASSET_HERE on INSERT_EXCHANGE_PROTOCOL_HERE, which means that we may be able to arbitrage it with INSERT_ALT_EXCHANGE_PROTOCOL_HERE.

To detect events, listen to the SSE Event Stream at [https://mev-share.flashbots.net](https://mev-share.flashbots.net). Client libraries exist for Typescript/Javascript and Rust (more coming soon) to simplify this:

<Tabs defaultValue="tsjs"
values={[
{label: 'TS/JS', value: 'tsjs'},
{label: 'Rust', value: 'rs'},
]}>
<TabItem value="tsjs">

[mev-share-client-ts](https://github.com/flashbots/mev-share-client-ts)

```typescript
// tsjs
```

// TODO: Explain specific typescript code here.

</TabItem>
<TabItem value="rs">

[mev-share-rs](https://github.com/paradigmxyz/mev-share-rs)

```typescript
// rs
```

// TODO: Explain specific rust code here.

</TabItem>
</Tabs>

## Filtering Relevant Transactions

// TODO: explain logs & default privacy settings on mev-share.

<Tabs defaultValue="tsjs"
values={[
{label: 'TS/JS', value: 'tsjs'},
{label: 'Rust', value: 'rs'},
]}>
<TabItem value="tsjs">

[mev-share-client-ts](https://github.com/flashbots/mev-share-client-ts)

```typescript
// tsjs
```

// TODO: Explain specific typescript code here.

</TabItem>
<TabItem value="rs">

[mev-share-rs](https://github.com/paradigmxyz/mev-share-rs)

```typescript
// rs
```

// TODO: Explain specific rust code here.

</TabItem>
</Tabs>

## Sending Backrun Bundles

<Tabs defaultValue="tsjs"
values={[
{label: 'TS/JS', value: 'tsjs'},
{label: 'Rust', value: 'rs'},
]}>
<TabItem value="tsjs">

[mev-share-client-ts](https://github.com/flashbots/mev-share-client-ts)

```typescript
// tsjs
```

// TODO: Explain specific typescript code here.

</TabItem>
<TabItem value="rs">

[mev-share-rs](https://github.com/paradigmxyz/mev-share-rs)

```typescript
// rs
```

// TODO: Explain specific rust code here.

</TabItem>
</Tabs>

For a full example, checkout our simple-blind-arbitrage bot written in Typescript.

TODO: nice wrap-up

** outline (deleteme) **

- watch event stream (mev-share mempool)
- parse log topic for pair address
- send backrun bundle

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Flash Loan Basics (Balancer)

To recap, flash loans allow us to borrow vast amounts of tokens, which we can use to pay for trades. If we make a profit from executing an arbitrage, we pay the loan back and keep what's left over. If the arbitrage fails or does not produce enough profit to repay the loan, the transaction reverts and Flashbots prevents it from landing onchain, so we don't pay any fees. The only fees we pay are gas fees for successful arbitrage trades.

We'll implement flash loans using Balancer, because they don't charge any loan fees, and have plenty of capital with which we can perform our arbitrage trades. Typically, flash loans (including Balancer) work by using callbacks. Callbacks are just functions that _other_ smart contracts call on _your_ smart contract. A callback in solidity is implemented by declaring a function in your smart contract with the exact name of the callback.

In the case of a flash loan on Balancer, which we'll implement shortly, the callback we have to create is the `receiveFlashLoan` function. When we want to get a flash loan, we'll call `vault.flashLoan`, where `vault` is the Balancer Vault smart contract, which holds the capital used for flash loans. In turn, the vault contract will call the `receiveFlashLoan` callback on our smart contract; this is where we'll put the code that performs an arbitrage trade and pays back the loan. That's all there is to it!
zeroXbrock marked this conversation as resolved.
Show resolved Hide resolved

## Adding Flash Loans to Your Contract

Flash loan capabilities can be added to any smart contract by simply implementing the `receiveFlashLoan` function. The only requirement for this function is that it pays back the flash loan, but we'll also call our arbitrage function here, since we only need flash loans for executing arbitrages.

Here's what it looks like in solidity:

```solidity
// TODO: add code
function receiveFlashLoan(...) external override {...}
```

Add this function to your existing smart contract, and then add a function that calls `vault.flashLoan`. Here's an example we borrowed from the [Balancer docs](https://docs.balancer.fi/reference/contracts/flash-loans.html#example-code):

```solidity
function makeFlashLoan(
IERC20[] memory tokens,
uint256[] memory amounts,
bytes memory userData
) external {
vault.flashLoan(this, tokens, amounts, userData);
}
```

We'll call `makeFlashLoan` to get a flash loan, which will in turn trigger the `receiveFlashLoan` function, which will execute the arbitrage trade and pay the loan back.

See [simple-blind-arbitrage](https://github.com/flashbots/simple-blind-arbitrage/blob/main/src/BlindBackrunFlashLoan.sol) for a ready-to-use flash loan smart contract.

Now that our contract is ready, we need to watch for new pending transactions and send arbitrage bundles to Flashbots when we find them. See the next page for instructions on writing a bot to do this for you.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Introduction

In this guide, we show you how to run an atomic arbitrage bot that uses flash loans. Flash loans allow you to borrow vast amounts of capital, which we'll use to pay for arbitrage trades. If you make a profit, then you pay back the loan and keep what's left over. If you don't, then the transaction simply reverts. Thanks to Flashbots, we don't pay for reverted transactions; we only have to pay gas for successful transactions. In sum, this is an ultra-low-risk strategy that requires very little upfront capital.

We'll start with a [turnkey bot](https://github.com/flashbots/simple-blind-arbitrage) you can run yourself. For a detailed description of how it works, see the next page.

---

- [simple-blind-arbitrage walkthrough video](https://youtu.be/Twcr2vZ1tRU?si=krmJbMH5htNTd-HK)
Loading