arbitrage
created at
Cosmos Arbitrage Bot 1
Hello!
I would like to explain in several articles how to create an Arbitrage Bot on Cosmos.
Why the Cosmos Chain?
For arbitrage on Dex, the most major chains are those compatible with EVM, such as Ethereum and Polygon. On these chains, not only are there convenient tools like Web3.py, but there are also various explanatory articles on the internet, making development relatively easy. However, this ease of development also means that there is a lot of competition.
Various Chains on Cosmos
Cosmos differs from the general image of a blockchain; it is more akin to a platform. On Cosmos, there are blockchains like the Osmosis chain and the KAVA chain, which are connected through a technology called IBC. These chains, compared to bridges in the EVM world, are far superior in terms of security. Arbitrage between chains using IBC is more cumbersome, but there are still profit opportunities to be found. This is one of the reasons for focusing on the Cosmos chain."
Target Audience
I will omit explanations of basic terms used in DeFi. The intention is to write in a manner understandable even to those who have no experience with Dex Bots.
Also, I believe there are many in this field who only know Python. However, Cosmos does not provide beginner-friendly tools like Web3.py. The Cosmos chain has a development kit written in the Go language, known as Cosmos SDK (similar to Geth in Ethereum), and it is often used for development. Therefore, in this series, we will use the Go language. Of course, it is also possible to retrieve pool information or send transactions using Python. Those who prefer to develop their bot in Python or Node.js instead of Go are encouraged to adapt and try out the provided code accordingly.
Prologue: Atomic Arbitrage on the Osmosis Chain
First, we will develop an Atomic Arbitrage (arbitrage within the same transaction) Bot on the Osmosis chain, which is the most liquid and major chain on Cosmos. This will serve as the basic form of a Debot (Decentralized Bot) on Cosmos.
Here is the English translation of your text:
Obtaining Necessary Information from Validators
First, let's start by obtaining the necessary price information through APIs from validators. The method to become a validator yourself will be explained in a later part.
The list of validators on Osmosis can be checked on websites like Mintscan. Major validators usually have an API available, so we will begin by using these to gather information about the pools.
import ( "encoding/json" "fmt" "io/ioutil" "net/http" ) type PoolAssets struct { Type string `json:"@type"` Id string Pool_params struct { Swap_fee string Exit_fee string } Pool_assets [2]struct { Token struct { Denom string Amount string } Weight string } } type PoolDetails struct { Pools []PoolAssets }
In Go language, type definitions are done in this way. When fetching information from an API, first use tools like Curl to preliminarily obtain the data, and then create a 'container' to store this data.
Next, we will use the "net/http" package to fetch information from the API."
func GetPoolAll() PoolDetails {
var url string
url = "https://api.osl.zone/osmosis/gamm/v1beta1/pools?pagination.limit=880".
// url = "https://api-osmosis-ia.cosmosia.notional.ventures/osmosis/gamm/v1beta1/pools?pagination.limit=880"
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var poolMap PoolDetails
json.Unmarshal(body, &poolMap)
return poolMap
}
Here's the translation of your text into English:
"Please use the addresses published by each validator for the URL. The communication speed may vary depending on the location of the server running the Bot, so I recommend trying out various APIs and choosing accordingly. Other than that, the process is a typical method of fetching an API in Go language.
Moreover, many pools within Osmosis are not active, so it might be beneficial to include code to exclude these. In this instance, we will create a function called GetActivePools(), using an API provided by a certain validator to narrow down the number of pools to monitor. Additionally, since this API call is only made once initially, it does not affect the speed of the operation.
type PoolCandidates struct {
Symbol string `json:"symbol"`
Denom string `json:"denom"`
Price float64 `json:"price"`
Fees string `json:"fees"`
}
// To reduce computational complexity, use pools that exclude less fluid pools.
func GetActivePools() map[int][2]PoolCandidates {
resp, err := http.Get("https://api-osmosis.imperator.co/pools/v2/all?low_liquidity=false")
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var poolMap map[int][2]PoolCandidates
json.Unmarshal(body, &poolMap)
return poolMap
}
Now let's prepare main.go and call these functions to get the price information.
func main() {
active_pools := GetActivePools()
whole_pools := GetPoolAll()
}
In the next article, we will start to use one of the features of the Go language, structs, to format and use this information. We also hope to explain and implement the Bellman-Ford method, which is a typical algorithm in Atmic Arb.
↓その2です