├── .env.example ├── .gitignore ├── Makefile ├── README.md ├── contract └── frontrunner │ ├── abi.json │ └── frontrunner.go ├── frontrunner-gif.gif ├── frontrunner.go ├── go.mod ├── go.sum └── scripts └── scores.go /.env.example: -------------------------------------------------------------------------------- 1 | RPC_URL="" 2 | PRIVATE_KEY="" 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include .env 2 | 3 | run-bot: 4 | RPC_URL=$(RPC_URL) PRIVATE_KEY=$(PRIVATE_KEY) go run . 5 | 6 | scores: 7 | RPC_URL=$(RPC_URL) go run scripts/scores.go 8 | 9 | contracts-bindings: 10 | abigen --abi ./contract/frontrunner/abi.json --pkg frontrunner --type Frontrunner --out ./contract/frontrunner/frontrunner.go 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FastLane Frontrunner Bot 2 | 3 | 💡We also have a python version of the bot [Here 🐍](https://github.com/FastLane-Labs/break-monad-frontrunner-bot-py) 4 | 5 |

6 | Frontrunner Game Animation 7 |

8 | 9 | The objective is simple, you compete as a searcher to be first to land a transaction on-chain in each new block. 10 | Your ranking is determined by your win/loss ratio weighted by number of attempts. 11 | 12 | ## Prerequisites 13 | 14 | ### 1. Install Go (Golang) 15 | 16 | First, you'll need to install Go on your computer: 17 | 18 | #### Windows: 19 | 20 | 1. Download the installer from [Go's official website](https://golang.org/dl/) 21 | 2. Run the installer and follow the prompts 22 | 3. Open Command Prompt and verify installation: 23 | 24 | ```sh 25 | go version 26 | ``` 27 | 28 | #### Mac: 29 | 30 | Using Homebrew: 31 | 32 | ```sh 33 | brew install go 34 | ``` 35 | 36 | #### Linux (Ubuntu/Debian): 37 | 38 | ```sh 39 | sudo apt update 40 | sudo apt install golang 41 | ``` 42 | 43 | ### 2. Set up your environment 44 | 45 | 1. Create a `.env` file in the project root directory 46 | 2. Generate a private key (if you don't have one): 47 | 48 | ```sh 49 | # Using OpenSSL (recommended) 50 | openssl rand -hex 32 51 | 52 | # Alternative: Using Python 53 | python3 -c "import secrets; print(secrets.token_hex(32))" 54 | ``` 55 | 56 | 3. To get your Ethereum address from the private key, use Python: 57 | 58 | ```sh 59 | # Install web3 if you haven't already 60 | pip install web3 61 | 62 | # Run this Python command (replace YOUR_PRIVATE_KEY with the key generated above) 63 | python3 -c "from web3 import Web3; w3 = Web3(); private_key = 'YOUR_PRIVATE_KEY'; account = w3.eth.account.from_key('0x' + private_key); print(f'Private key: {private_key}'); print(f'Public address: {account.address}')" 64 | ``` 65 | 66 | Additionally, your private key can sometimes be found in your wallet settings. 67 | 68 | 4. Add your configuration: 69 | 70 | ```sh 71 | PRIVATE_KEY=your_private_key_here 72 | RPC_URL=your_rpc_url_here 73 | ``` 74 | 75 | ⚠️ IMPORTANT SECURITY NOTES: 76 | 77 | - NEVER share your private key or commit it to version control! 78 | - Store your private key securely and keep a backup 79 | 80 | Additional RPC URLs: 81 | 82 | ``` 83 | London: https://rpc.monad-testnet-2.fastlane.xyz/b3qFoDfY9sR44yRyOeHAfyj9dpEXVoOC 84 | Bogota: https://rpc.monad-testnet-3.fastlane.xyz/j6EsEZHfw9Iqrp7DUX5e1aLUk85d1Yzw 85 | Singapore: https://rpc.monad-testnet-5.fastlane.xyz/FFHEYATiGl2Q83xOnf71ltrqZ57q9U1W 86 | ``` 87 | 88 | ## Common Commands 89 | 90 | ### Run the bot 91 | 92 | ```sh 93 | make run-bot 94 | # or 95 | go run cmd/bot/main.go 96 | ``` 97 | 98 | ### Check current scores 99 | 100 | ```sh 101 | make scores 102 | # or 103 | go run cmd/scores/main.go 104 | ``` 105 | 106 | ## Troubleshooting 107 | 108 | If you encounter any issues: 109 | 110 | 1. Make sure Go is properly installed: 111 | 112 | ```sh 113 | go version 114 | ``` 115 | 116 | 2. Verify your `.env` file exists and contains valid credentials 117 | 3. Ensure all dependencies are installed: 118 | 119 | ```sh 120 | go mod tidy 121 | ``` 122 | 123 | ## Need Help? 124 | 125 | - Ask for help in the FastLane on Monad Discord (#frontunner channel) 126 | - Talk to ChatGPT 127 | - Create an issue in this repository 128 | - Make sure your Go environment variables are set correctly: 129 | 130 | ```sh 131 | go env 132 | ``` 133 | 134 | ## License 135 | 136 | MIT 137 | -------------------------------------------------------------------------------- /contract/frontrunner/abi.json: -------------------------------------------------------------------------------- 1 | [{"type":"function","name":"frontrun","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"getScore","inputs":[{"name":"_address","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"tuple","internalType":"struct Frontrunner.ParticipantData","components":[{"name":"Address","type":"address","internalType":"address"},{"name":"Wins","type":"uint256","internalType":"uint256"},{"name":"Losses","type":"uint256","internalType":"uint256"}]}],"stateMutability":"view"},{"type":"function","name":"getScores","inputs":[],"outputs":[{"name":"","type":"tuple[]","internalType":"struct Frontrunner.ParticipantData[]","components":[{"name":"Address","type":"address","internalType":"address"},{"name":"Wins","type":"uint256","internalType":"uint256"},{"name":"Losses","type":"uint256","internalType":"uint256"}]}],"stateMutability":"view"}] -------------------------------------------------------------------------------- /contract/frontrunner/frontrunner.go: -------------------------------------------------------------------------------- 1 | // Code generated - DO NOT EDIT. 2 | // This file is a generated binding and any manual changes will be lost. 3 | 4 | package frontrunner 5 | 6 | import ( 7 | "errors" 8 | "math/big" 9 | "strings" 10 | 11 | ethereum "github.com/ethereum/go-ethereum" 12 | "github.com/ethereum/go-ethereum/accounts/abi" 13 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 14 | "github.com/ethereum/go-ethereum/common" 15 | "github.com/ethereum/go-ethereum/core/types" 16 | "github.com/ethereum/go-ethereum/event" 17 | ) 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var ( 21 | _ = errors.New 22 | _ = big.NewInt 23 | _ = strings.NewReader 24 | _ = ethereum.NotFound 25 | _ = bind.Bind 26 | _ = common.Big1 27 | _ = types.BloomLookup 28 | _ = event.NewSubscription 29 | ) 30 | 31 | // FrontrunnerParticipantData is an auto generated low-level Go binding around an user-defined struct. 32 | type FrontrunnerParticipantData struct { 33 | Address common.Address 34 | Wins *big.Int 35 | Losses *big.Int 36 | } 37 | 38 | // FrontrunnerMetaData contains all meta data concerning the Frontrunner contract. 39 | var FrontrunnerMetaData = &bind.MetaData{ 40 | ABI: "[{\"type\":\"function\",\"name\":\"frontrun\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"getScore\",\"inputs\":[{\"name\":\"_address\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structFrontrunner.ParticipantData\",\"components\":[{\"name\":\"Address\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"Wins\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Losses\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getScores\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple[]\",\"internalType\":\"structFrontrunner.ParticipantData[]\",\"components\":[{\"name\":\"Address\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"Wins\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"Losses\",\"type\":\"uint256\",\"internalType\":\"uint256\"}]}],\"stateMutability\":\"view\"}]", 41 | } 42 | 43 | // FrontrunnerABI is the input ABI used to generate the binding from. 44 | // Deprecated: Use FrontrunnerMetaData.ABI instead. 45 | var FrontrunnerABI = FrontrunnerMetaData.ABI 46 | 47 | // Frontrunner is an auto generated Go binding around an Ethereum contract. 48 | type Frontrunner struct { 49 | FrontrunnerCaller // Read-only binding to the contract 50 | FrontrunnerTransactor // Write-only binding to the contract 51 | FrontrunnerFilterer // Log filterer for contract events 52 | } 53 | 54 | // FrontrunnerCaller is an auto generated read-only Go binding around an Ethereum contract. 55 | type FrontrunnerCaller struct { 56 | contract *bind.BoundContract // Generic contract wrapper for the low level calls 57 | } 58 | 59 | // FrontrunnerTransactor is an auto generated write-only Go binding around an Ethereum contract. 60 | type FrontrunnerTransactor struct { 61 | contract *bind.BoundContract // Generic contract wrapper for the low level calls 62 | } 63 | 64 | // FrontrunnerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. 65 | type FrontrunnerFilterer struct { 66 | contract *bind.BoundContract // Generic contract wrapper for the low level calls 67 | } 68 | 69 | // FrontrunnerSession is an auto generated Go binding around an Ethereum contract, 70 | // with pre-set call and transact options. 71 | type FrontrunnerSession struct { 72 | Contract *Frontrunner // Generic contract binding to set the session for 73 | CallOpts bind.CallOpts // Call options to use throughout this session 74 | TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session 75 | } 76 | 77 | // FrontrunnerCallerSession is an auto generated read-only Go binding around an Ethereum contract, 78 | // with pre-set call options. 79 | type FrontrunnerCallerSession struct { 80 | Contract *FrontrunnerCaller // Generic contract caller binding to set the session for 81 | CallOpts bind.CallOpts // Call options to use throughout this session 82 | } 83 | 84 | // FrontrunnerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, 85 | // with pre-set transact options. 86 | type FrontrunnerTransactorSession struct { 87 | Contract *FrontrunnerTransactor // Generic contract transactor binding to set the session for 88 | TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session 89 | } 90 | 91 | // FrontrunnerRaw is an auto generated low-level Go binding around an Ethereum contract. 92 | type FrontrunnerRaw struct { 93 | Contract *Frontrunner // Generic contract binding to access the raw methods on 94 | } 95 | 96 | // FrontrunnerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. 97 | type FrontrunnerCallerRaw struct { 98 | Contract *FrontrunnerCaller // Generic read-only contract binding to access the raw methods on 99 | } 100 | 101 | // FrontrunnerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. 102 | type FrontrunnerTransactorRaw struct { 103 | Contract *FrontrunnerTransactor // Generic write-only contract binding to access the raw methods on 104 | } 105 | 106 | // NewFrontrunner creates a new instance of Frontrunner, bound to a specific deployed contract. 107 | func NewFrontrunner(address common.Address, backend bind.ContractBackend) (*Frontrunner, error) { 108 | contract, err := bindFrontrunner(address, backend, backend, backend) 109 | if err != nil { 110 | return nil, err 111 | } 112 | return &Frontrunner{FrontrunnerCaller: FrontrunnerCaller{contract: contract}, FrontrunnerTransactor: FrontrunnerTransactor{contract: contract}, FrontrunnerFilterer: FrontrunnerFilterer{contract: contract}}, nil 113 | } 114 | 115 | // NewFrontrunnerCaller creates a new read-only instance of Frontrunner, bound to a specific deployed contract. 116 | func NewFrontrunnerCaller(address common.Address, caller bind.ContractCaller) (*FrontrunnerCaller, error) { 117 | contract, err := bindFrontrunner(address, caller, nil, nil) 118 | if err != nil { 119 | return nil, err 120 | } 121 | return &FrontrunnerCaller{contract: contract}, nil 122 | } 123 | 124 | // NewFrontrunnerTransactor creates a new write-only instance of Frontrunner, bound to a specific deployed contract. 125 | func NewFrontrunnerTransactor(address common.Address, transactor bind.ContractTransactor) (*FrontrunnerTransactor, error) { 126 | contract, err := bindFrontrunner(address, nil, transactor, nil) 127 | if err != nil { 128 | return nil, err 129 | } 130 | return &FrontrunnerTransactor{contract: contract}, nil 131 | } 132 | 133 | // NewFrontrunnerFilterer creates a new log filterer instance of Frontrunner, bound to a specific deployed contract. 134 | func NewFrontrunnerFilterer(address common.Address, filterer bind.ContractFilterer) (*FrontrunnerFilterer, error) { 135 | contract, err := bindFrontrunner(address, nil, nil, filterer) 136 | if err != nil { 137 | return nil, err 138 | } 139 | return &FrontrunnerFilterer{contract: contract}, nil 140 | } 141 | 142 | // bindFrontrunner binds a generic wrapper to an already deployed contract. 143 | func bindFrontrunner(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { 144 | parsed, err := abi.JSON(strings.NewReader(FrontrunnerABI)) 145 | if err != nil { 146 | return nil, err 147 | } 148 | return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil 149 | } 150 | 151 | // Call invokes the (constant) contract method with params as input values and 152 | // sets the output to result. The result type might be a single field for simple 153 | // returns, a slice of interfaces for anonymous returns and a struct for named 154 | // returns. 155 | func (_Frontrunner *FrontrunnerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { 156 | return _Frontrunner.Contract.FrontrunnerCaller.contract.Call(opts, result, method, params...) 157 | } 158 | 159 | // Transfer initiates a plain transaction to move funds to the contract, calling 160 | // its default method if one is available. 161 | func (_Frontrunner *FrontrunnerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { 162 | return _Frontrunner.Contract.FrontrunnerTransactor.contract.Transfer(opts) 163 | } 164 | 165 | // Transact invokes the (paid) contract method with params as input values. 166 | func (_Frontrunner *FrontrunnerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { 167 | return _Frontrunner.Contract.FrontrunnerTransactor.contract.Transact(opts, method, params...) 168 | } 169 | 170 | // Call invokes the (constant) contract method with params as input values and 171 | // sets the output to result. The result type might be a single field for simple 172 | // returns, a slice of interfaces for anonymous returns and a struct for named 173 | // returns. 174 | func (_Frontrunner *FrontrunnerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { 175 | return _Frontrunner.Contract.contract.Call(opts, result, method, params...) 176 | } 177 | 178 | // Transfer initiates a plain transaction to move funds to the contract, calling 179 | // its default method if one is available. 180 | func (_Frontrunner *FrontrunnerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { 181 | return _Frontrunner.Contract.contract.Transfer(opts) 182 | } 183 | 184 | // Transact invokes the (paid) contract method with params as input values. 185 | func (_Frontrunner *FrontrunnerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { 186 | return _Frontrunner.Contract.contract.Transact(opts, method, params...) 187 | } 188 | 189 | // GetScore is a free data retrieval call binding the contract method 0xd47875d0. 190 | // 191 | // Solidity: function getScore(address _address) view returns((address,uint256,uint256)) 192 | func (_Frontrunner *FrontrunnerCaller) GetScore(opts *bind.CallOpts, _address common.Address) (FrontrunnerParticipantData, error) { 193 | var out []interface{} 194 | err := _Frontrunner.contract.Call(opts, &out, "getScore", _address) 195 | 196 | if err != nil { 197 | return *new(FrontrunnerParticipantData), err 198 | } 199 | 200 | out0 := *abi.ConvertType(out[0], new(FrontrunnerParticipantData)).(*FrontrunnerParticipantData) 201 | 202 | return out0, err 203 | 204 | } 205 | 206 | // GetScore is a free data retrieval call binding the contract method 0xd47875d0. 207 | // 208 | // Solidity: function getScore(address _address) view returns((address,uint256,uint256)) 209 | func (_Frontrunner *FrontrunnerSession) GetScore(_address common.Address) (FrontrunnerParticipantData, error) { 210 | return _Frontrunner.Contract.GetScore(&_Frontrunner.CallOpts, _address) 211 | } 212 | 213 | // GetScore is a free data retrieval call binding the contract method 0xd47875d0. 214 | // 215 | // Solidity: function getScore(address _address) view returns((address,uint256,uint256)) 216 | func (_Frontrunner *FrontrunnerCallerSession) GetScore(_address common.Address) (FrontrunnerParticipantData, error) { 217 | return _Frontrunner.Contract.GetScore(&_Frontrunner.CallOpts, _address) 218 | } 219 | 220 | // GetScores is a free data retrieval call binding the contract method 0x1ea1380c. 221 | // 222 | // Solidity: function getScores() view returns((address,uint256,uint256)[]) 223 | func (_Frontrunner *FrontrunnerCaller) GetScores(opts *bind.CallOpts) ([]FrontrunnerParticipantData, error) { 224 | var out []interface{} 225 | err := _Frontrunner.contract.Call(opts, &out, "getScores") 226 | 227 | if err != nil { 228 | return *new([]FrontrunnerParticipantData), err 229 | } 230 | 231 | out0 := *abi.ConvertType(out[0], new([]FrontrunnerParticipantData)).(*[]FrontrunnerParticipantData) 232 | 233 | return out0, err 234 | 235 | } 236 | 237 | // GetScores is a free data retrieval call binding the contract method 0x1ea1380c. 238 | // 239 | // Solidity: function getScores() view returns((address,uint256,uint256)[]) 240 | func (_Frontrunner *FrontrunnerSession) GetScores() ([]FrontrunnerParticipantData, error) { 241 | return _Frontrunner.Contract.GetScores(&_Frontrunner.CallOpts) 242 | } 243 | 244 | // GetScores is a free data retrieval call binding the contract method 0x1ea1380c. 245 | // 246 | // Solidity: function getScores() view returns((address,uint256,uint256)[]) 247 | func (_Frontrunner *FrontrunnerCallerSession) GetScores() ([]FrontrunnerParticipantData, error) { 248 | return _Frontrunner.Contract.GetScores(&_Frontrunner.CallOpts) 249 | } 250 | 251 | // Frontrun is a paid mutator transaction binding the contract method 0x0c60e091. 252 | // 253 | // Solidity: function frontrun() returns() 254 | func (_Frontrunner *FrontrunnerTransactor) Frontrun(opts *bind.TransactOpts) (*types.Transaction, error) { 255 | return _Frontrunner.contract.Transact(opts, "frontrun") 256 | } 257 | 258 | // Frontrun is a paid mutator transaction binding the contract method 0x0c60e091. 259 | // 260 | // Solidity: function frontrun() returns() 261 | func (_Frontrunner *FrontrunnerSession) Frontrun() (*types.Transaction, error) { 262 | return _Frontrunner.Contract.Frontrun(&_Frontrunner.TransactOpts) 263 | } 264 | 265 | // Frontrun is a paid mutator transaction binding the contract method 0x0c60e091. 266 | // 267 | // Solidity: function frontrun() returns() 268 | func (_Frontrunner *FrontrunnerTransactorSession) Frontrun() (*types.Transaction, error) { 269 | return _Frontrunner.Contract.Frontrun(&_Frontrunner.TransactOpts) 270 | } 271 | -------------------------------------------------------------------------------- /frontrunner-gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FastLane-Labs/break-monad-frontrunner-bot/d84befdb3ce79b43f781c7d41691b23b204b4f86/frontrunner-gif.gif -------------------------------------------------------------------------------- /frontrunner.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "math/big" 6 | "os" 7 | "os/signal" 8 | "time" 9 | 10 | "github.com/FastLane-Labs/break-monad-frontrunner-bot/contract/frontrunner" 11 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 12 | "github.com/ethereum/go-ethereum/common" 13 | "github.com/ethereum/go-ethereum/core/types" 14 | "github.com/ethereum/go-ethereum/crypto" 15 | "github.com/ethereum/go-ethereum/ethclient" 16 | "github.com/ethereum/go-ethereum/log" 17 | "golang.org/x/sync/errgroup" 18 | ) 19 | 20 | var ( 21 | frontrunnerContractAddress = common.HexToAddress("0xBce2C725304e09CEf4cD7639760B67f8A0Af5bc4") 22 | taskInterval = 1 * time.Second 23 | ) 24 | 25 | func main() { 26 | log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stdout, log.LvlDebug, true))) 27 | 28 | ethClient, err := ethclient.Dial(os.Getenv("RPC_URL")) 29 | if err != nil { 30 | log.Error("failed to connect to Ethereum client", "error", err) 31 | os.Exit(1) 32 | } 33 | 34 | chainId, err := ethClient.ChainID(context.TODO()) 35 | if err != nil { 36 | log.Error("failed to get chain ID", "error", err) 37 | os.Exit(1) 38 | } 39 | 40 | pk, err := crypto.HexToECDSA(os.Getenv("PRIVATE_KEY")) 41 | if err != nil { 42 | log.Error("failed to parse private key", "error", err) 43 | os.Exit(1) 44 | } 45 | 46 | executor, err := bind.NewKeyedTransactorWithChainID(pk, chainId) 47 | if err != nil { 48 | log.Error("failed to create executor", "error", err) 49 | os.Exit(1) 50 | } 51 | 52 | frontrunnerContract, err := frontrunner.NewFrontrunner(frontrunnerContractAddress, ethClient) 53 | if err != nil { 54 | log.Error("failed to create Frontrunner contract", "error", err) 55 | os.Exit(1) 56 | } 57 | 58 | interrupt := make(chan os.Signal, 1) 59 | signal.Notify(interrupt, os.Interrupt) 60 | 61 | go runBot(executor, frontrunnerContract, ethClient) 62 | 63 | <-interrupt 64 | } 65 | 66 | func runBot(executor *bind.TransactOpts, frontrunnerContract *frontrunner.Frontrunner, ethClient *ethclient.Client) { 67 | ticker := time.NewTicker(taskInterval) 68 | defer ticker.Stop() 69 | 70 | for range ticker.C { 71 | feeCap, tipCap, err := getGasPrice(ethClient) 72 | if err != nil { 73 | log.Error("failed to get gas price", "error", err) 74 | continue 75 | } 76 | 77 | executor.GasFeeCap = feeCap 78 | executor.GasTipCap = tipCap 79 | 80 | log.Info("sending frontrun", "maxFeePerGas", feeCap, "maxPriorityFeePerGas", tipCap) 81 | 82 | tx, err := frontrunnerContract.Frontrun(executor) 83 | if err != nil { 84 | log.Error("failed to frontrun", "error", err) 85 | continue 86 | } 87 | 88 | log.Info("frontrun sent, waiting for confirmation", "hash", tx.Hash().Hex()) 89 | 90 | receipt, err := bind.WaitMined(context.TODO(), ethClient, tx) 91 | if err != nil { 92 | log.Error("failed to land frontrun", "error", err) 93 | continue 94 | } 95 | 96 | log.Info("confirmed frontrun", "reverted", receipt.Status == types.ReceiptStatusFailed) 97 | } 98 | } 99 | 100 | // Returns calculated (maxFeePerGas, maxPriorityFeePerGas), override with better logic 101 | func getGasPrice(ethClient *ethclient.Client) (*big.Int, *big.Int, error) { 102 | var ( 103 | feeCap *big.Int 104 | tipCap *big.Int 105 | g, _ = errgroup.WithContext(context.TODO()) 106 | ) 107 | 108 | g.Go(func() error { 109 | _feeCap, err := ethClient.SuggestGasPrice(context.TODO()) 110 | if err != nil { 111 | return err 112 | } 113 | 114 | feeCap = _feeCap 115 | return nil 116 | }) 117 | 118 | g.Go(func() error { 119 | _tipCap, err := ethClient.SuggestGasTipCap(context.TODO()) 120 | if err != nil { 121 | return err 122 | } 123 | 124 | tipCap = _tipCap 125 | return nil 126 | }) 127 | 128 | if err := g.Wait(); err != nil { 129 | return nil, nil, err 130 | } 131 | 132 | return feeCap, tipCap, nil 133 | } 134 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/FastLane-Labs/break-monad-frontrunner-bot 2 | 3 | go 1.22.2 4 | 5 | require ( 6 | github.com/ethereum/go-ethereum v1.14.13 7 | golang.org/x/sync v0.7.0 8 | ) 9 | 10 | require ( 11 | github.com/Microsoft/go-winio v0.6.2 // indirect 12 | github.com/StackExchange/wmi v1.2.1 // indirect 13 | github.com/bits-and-blooms/bitset v1.13.0 // indirect 14 | github.com/consensys/bavard v0.1.13 // indirect 15 | github.com/consensys/gnark-crypto v0.12.1 // indirect 16 | github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect 17 | github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect 18 | github.com/deckarep/golang-set/v2 v2.6.0 // indirect 19 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect 20 | github.com/ethereum/c-kzg-4844 v1.0.0 // indirect 21 | github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect 22 | github.com/fsnotify/fsnotify v1.6.0 // indirect 23 | github.com/go-ole/go-ole v1.3.0 // indirect 24 | github.com/google/uuid v1.3.0 // indirect 25 | github.com/gorilla/websocket v1.4.2 // indirect 26 | github.com/holiman/uint256 v1.3.1 // indirect 27 | github.com/mmcloughlin/addchain v0.4.0 // indirect 28 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect 29 | github.com/supranational/blst v0.3.13 // indirect 30 | github.com/tklauser/go-sysconf v0.3.12 // indirect 31 | github.com/tklauser/numcpus v0.6.1 // indirect 32 | golang.org/x/crypto v0.22.0 // indirect 33 | golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect 34 | golang.org/x/sys v0.22.0 // indirect 35 | rsc.io/tmplfunc v0.0.3 // indirect 36 | ) 37 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= 2 | github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= 3 | github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= 4 | github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= 5 | github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= 6 | github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= 7 | github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= 8 | github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= 9 | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 10 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 11 | github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= 12 | github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= 13 | github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= 14 | github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= 15 | github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= 16 | github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 17 | github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= 18 | github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= 19 | github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= 20 | github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= 21 | github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= 22 | github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= 23 | github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= 24 | github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= 25 | github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= 26 | github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= 27 | github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= 28 | github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= 29 | github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= 30 | github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= 31 | github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= 32 | github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= 33 | github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= 34 | github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 35 | github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= 36 | github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= 37 | github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= 38 | github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= 39 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 40 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 41 | github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= 42 | github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= 43 | github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= 44 | github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= 45 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= 46 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= 47 | github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= 48 | github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= 49 | github.com/ethereum/go-ethereum v1.14.13 h1:L81Wmv0OUP6cf4CW6wtXsr23RUrDhKs2+Y9Qto+OgHU= 50 | github.com/ethereum/go-ethereum v1.14.13/go.mod h1:RAC2gVMWJ6FkxSPESfbshrcKpIokgQKsVKmAuqdekDY= 51 | github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= 52 | github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= 53 | github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= 54 | github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= 55 | github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= 56 | github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= 57 | github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= 58 | github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= 59 | github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= 60 | github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= 61 | github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= 62 | github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= 63 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 64 | github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= 65 | github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= 66 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 67 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 68 | github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= 69 | github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 70 | github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= 71 | github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 72 | github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= 73 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 74 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 75 | github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= 76 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 77 | github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= 78 | github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= 79 | github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= 80 | github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= 81 | github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= 82 | github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= 83 | github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= 84 | github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= 85 | github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= 86 | github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= 87 | github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= 88 | github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= 89 | github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= 90 | github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= 91 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 92 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 93 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 94 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 95 | github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= 96 | github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= 97 | github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= 98 | github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= 99 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 100 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 101 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 102 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 103 | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= 104 | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 105 | github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= 106 | github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= 107 | github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= 108 | github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 109 | github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= 110 | github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= 111 | github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= 112 | github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= 113 | github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= 114 | github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= 115 | github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 116 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 117 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 118 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 119 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 120 | github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= 121 | github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= 122 | github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= 123 | github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= 124 | github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= 125 | github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= 126 | github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= 127 | github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= 128 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= 129 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 130 | github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= 131 | github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= 132 | github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= 133 | github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= 134 | github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 135 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 136 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= 137 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= 138 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 139 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 140 | github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= 141 | github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= 142 | github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= 143 | github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= 144 | github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= 145 | github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= 146 | github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= 147 | github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= 148 | github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= 149 | github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= 150 | github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= 151 | github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= 152 | golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= 153 | golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= 154 | golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= 155 | golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= 156 | golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= 157 | golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 158 | golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 159 | golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 160 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 161 | golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 162 | golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 163 | golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= 164 | golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 165 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 166 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 167 | golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= 168 | golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= 169 | google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= 170 | google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 171 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= 172 | gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= 173 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 174 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 175 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 176 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 177 | rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= 178 | rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= 179 | -------------------------------------------------------------------------------- /scripts/scores.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/FastLane-Labs/break-monad-frontrunner-bot/contract/frontrunner" 8 | "github.com/ethereum/go-ethereum/common" 9 | "github.com/ethereum/go-ethereum/ethclient" 10 | ) 11 | 12 | var ( 13 | frontrunnerContractAddress = common.HexToAddress("0x9EaBA701a49adE7525dFfE338f0C7E06Eca7Cf07") 14 | ) 15 | 16 | func main() { 17 | ethClient, err := ethclient.Dial(os.Getenv("RPC_URL")) 18 | if err != nil { 19 | fmt.Println("failed to connect to Ethereum client", "error", err) 20 | os.Exit(1) 21 | } 22 | 23 | frontrunnerContract, err := frontrunner.NewFrontrunner(frontrunnerContractAddress, ethClient) 24 | if err != nil { 25 | fmt.Println("failed to create Frontrunner contract", "error", err) 26 | os.Exit(1) 27 | } 28 | 29 | scores, err := frontrunnerContract.GetScores(nil) 30 | if err != nil { 31 | fmt.Println("failed to get scores", "error", err) 32 | os.Exit(1) 33 | } 34 | 35 | fmt.Println("Address", "Wins/Losses") 36 | 37 | for _, score := range scores { 38 | fmt.Printf("%s %s/%s\n", score.Address.Hex(), score.Wins, score.Losses) 39 | } 40 | } 41 | --------------------------------------------------------------------------------