for-searchers
Participating validators
- 0x742d13f0b2a19c823bdd362b16305e4704b97a38 (InfStones)
- 0x8842ea85732f94feeb9cf1ccc7d357c63658e7a4 (Chorus One)
- 0xe63727cb2b3a8d6e3a2d1df4990f441938b67a34 (Nobi)
Note that this list might not be up-to-date. Please make a pull request or reach out on discord to list your validator here.
Endpoint
Searchers can use the following relay endpoint to send bundles:
Searchers might want to run their nodes near Germany to get good latency to the relay and the validators.
mev-bor spec
mev-bor follows the Flashbots v0.3 spec (https://docs.flashbots.net/flashbots-auction/miners/mev-geth-spec/v03-rpc) with the following changes:
-
The RPC methods have been moved from the
eth
namespace to a newmev
namespace. This was done to enable validators to not expose theeth
namespace which contains a lot more unrelated RPC methods as well as security critical methods like signing using the unlocked validator key. mev relay spec The MEV relay is designed to work with the flashbots bundle formats, RPC calls and the flashbots ethers provider (https://github.com/flashbots/ethers-provider-flashbots-bundle) with the following notable changes: -
The relay only supports the
eth_sendBundle
RPC call at the moment. This means methods likeeth_callBundle
and related calls likesimulate
in the flashbots provider are not supported. Searchers will need their own instance or bor/mev-bor if they require the use of these methods. -
The relay currently only accepts bundles with up to 5 transactions with a cumulative gas limit of 2.5M gas. These limits are expected to go up in the future as we collect more metrics regarding usage and capacity requirements.
-
The
revertingTxHashes
field in the bundle isn't supported currently.
Note that bundle delivery and inclusion is best effort, and searchers still have to make sure that bundles do not spam the endpoints and are economically enticing for validators to include, moreso than transactions from other bundles and public mempool.
Example usage
import { providers, Wallet } from "ethers";
import { FlashbotsBundleProvider } from "@flashbots/ethers-provider-bundle";
async function main() {
// Standard json rpc provider directly from ethers.js (NOT Flashbots)
// create the base provider
let base = new ethers.providers.JsonRpcProvider({url: "http://<polygonbor-ip>:8545"}, 137)
await base.ready
const user = new ethers.Wallet('a2..<privkey>..40', base)
// wrap it with the marlin relay provider
let provider = new FlashbotsBundleProvider(base, user, {url: 'http://bor.txrelay.marlin.org/'}, 137)
const CONTRACT_ADDRESS = "0x0a..<contract-address>"
const ABI = ["function coinbasetransfer() payable"]
const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, user)
const txs = [
{
signer: user,
transaction: await contract.populateTransaction.coinbasetransfer({
value: ethers.utils.parseEther("0.1"),
gasPrice: "31000000000",
})
},
{
signer: user,
transaction: await contract.populateTransaction.coinbasetransfer({
value: ethers.utils.parseEther("0.2"),
gasPrice: "31000000000",
})
},
];
const blk = await base.getBlockNumber()
// send bundle to marlin relay
const result = await provider.sendBundle(txs, blk + 1);
console.log(result)
}
main().catch(console.error)