This commit is contained in:
Jarett Dunn 2024-11-21 20:17:54 +00:00 committed by GitHub
commit 167066f993
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 873 additions and 490 deletions

558
Cargo.lock generated
View File

@ -273,7 +273,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c4fd6e43b2ca6220d2ef1641539e678bfc31b6cc393cf892b373b5997b6a39a"
dependencies = [
"anchor-lang",
"mpl-token-metadata",
"mpl-token-metadata 3.2.3",
"solana-program",
"spl-associated-token-account 2.3.0",
"spl-token 4.0.0",
@ -376,12 +376,6 @@ version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "ark-bn254"
version = "0.4.0"
@ -511,12 +505,6 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "arrayvec"
version = "0.7.4"
@ -538,7 +526,7 @@ dependencies = [
"asn1-rs-derive",
"asn1-rs-impl",
"displaydoc",
"nom 7.1.3",
"nom",
"num-traits",
"rusticata-macros",
"thiserror",
@ -718,9 +706,9 @@ dependencies = [
"bytes 1.6.0",
"chrono",
"clap 3.2.25",
"dex-gobbler",
"dex-infinity",
"dex-invariant",
"dex-openbook-v2",
"dex-orca",
"dex-raydium",
"dex-raydium-cp",
@ -1040,7 +1028,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52"
dependencies = [
"arrayref",
"arrayvec 0.7.4",
"arrayvec",
"cc",
"cfg-if 1.0.0",
"constant_time_eq",
@ -1754,17 +1742,6 @@ dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "cron"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f8c3e73077b4b4a6ab1ea5047c37c57aee77657bc8ecd6f29b0af082d0b0c07"
dependencies = [
"chrono",
"nom 7.1.3",
"once_cell",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.12"
@ -1949,19 +1926,6 @@ dependencies = [
"rayon",
]
[[package]]
name = "dashmap"
version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
dependencies = [
"cfg-if 1.0.0",
"hashbrown 0.14.3",
"lock_api 0.4.11",
"once_cell",
"parking_lot_core 0.9.9",
]
[[package]]
name = "dashmap"
version = "6.0.1"
@ -2032,7 +1996,7 @@ checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e"
dependencies = [
"asn1-rs",
"displaydoc",
"nom 7.1.3",
"nom",
"num-bigint 0.4.6",
"num-traits",
"rusticata-macros",
@ -2109,6 +2073,35 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "dex-gobbler"
version = "0.0.1"
dependencies = [
"anchor-client",
"anchor-lang",
"anchor-spl",
"anyhow",
"async-trait",
"chrono",
"gobblerdev",
"itertools 0.10.5",
"mango-feeds-connector",
"router-feed-lib",
"router-lib",
"router-test-lib",
"serde",
"serde_derive",
"sha2 0.10.8",
"solana-account-decoder",
"solana-client",
"solana-logger",
"solana-program",
"solana-program-test",
"solana-sdk",
"spl-associated-token-account 1.1.3",
"tracing",
]
[[package]]
name = "dex-infinity"
version = "0.0.1"
@ -2178,36 +2171,6 @@ dependencies = [
"uint",
]
[[package]]
name = "dex-openbook-v2"
version = "0.0.1"
dependencies = [
"anchor-client",
"anchor-lang",
"anchor-spl",
"anyhow",
"async-trait",
"bytemuck",
"chrono",
"itertools 0.10.5",
"mango-feeds-connector",
"openbook-v2",
"router-feed-lib",
"router-lib",
"router-test-lib",
"serde",
"serde_derive",
"sha2 0.10.8",
"solana-account-decoder",
"solana-client",
"solana-logger",
"solana-program",
"solana-program-test",
"solana-sdk",
"spl-associated-token-account 1.1.3",
"tracing",
]
[[package]]
name = "dex-orca"
version = "0.0.1"
@ -2436,12 +2399,6 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "dyn-clone"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
[[package]]
name = "eager"
version = "0.1.0"
@ -2562,30 +2519,12 @@ dependencies = [
"termcolor",
]
[[package]]
name = "envy"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965"
dependencies = [
"serde",
]
[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "erased-serde"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b73807008a3c7f171cc40312f37d95ef0396e048b5848d775f54b1a4dd4a0d3"
dependencies = [
"serde",
]
[[package]]
name = "errno"
version = "0.3.8"
@ -2644,10 +2583,8 @@ version = "1.11.0"
source = "git+https://github.com/blockworks-foundation/fixed.git?branch=v1.11.0-borsh0_10-mango#01516ae3e29418feb066b67830540aa81d04df05"
dependencies = [
"az",
"borsh 0.10.3",
"bytemuck",
"half",
"serde",
"typenum",
]
@ -2969,6 +2906,25 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "gobblerdev"
version = "0.1.142"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "920c1e6c00418753a380c5677149b49e1a573b8b6226d2bc4508495942968fce"
dependencies = [
"anchor-lang",
"anchor-spl",
"arrayref",
"bytemuck",
"mpl-token-metadata 4.1.2",
"solana-program",
"solana-security-txt",
"spl-math",
"spl-memo 4.0.0",
"spl-token 4.0.0",
"uint",
]
[[package]]
name = "goblin"
version = "0.5.4"
@ -3076,7 +3032,7 @@ dependencies = [
"byteorder",
"crossbeam-channel",
"flate2 1.0.28",
"nom 7.1.3",
"nom",
"num-traits",
]
@ -3145,9 +3101,6 @@ name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
dependencies = [
"serde",
]
[[package]]
name = "histogram"
@ -3801,15 +3754,6 @@ dependencies = [
"winapi-build",
]
[[package]]
name = "kv-log-macro"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
dependencies = [
"log 0.4.21",
]
[[package]]
name = "language-tags"
version = "0.2.2"
@ -3822,19 +3766,6 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lexical-core"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
dependencies = [
"arrayvec 0.5.2",
"bitflags 1.3.2",
"cfg-if 1.0.0",
"ryu",
"static_assertions",
]
[[package]]
name = "libc"
version = "0.2.153"
@ -4008,9 +3939,6 @@ name = "log"
version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
dependencies = [
"value-bag",
]
[[package]]
name = "lru"
@ -4326,6 +4254,19 @@ dependencies = [
"thiserror",
]
[[package]]
name = "mpl-token-metadata"
version = "4.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf0f61b553e424a6234af1268456972ee66c2222e1da89079242251fa7479e5"
dependencies = [
"borsh 0.10.3",
"num-derive 0.3.3",
"num-traits",
"solana-program",
"thiserror",
]
[[package]]
name = "multer"
version = "2.1.0"
@ -4392,17 +4333,6 @@ dependencies = [
"pin-utils",
]
[[package]]
name = "nom"
version = "5.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b"
dependencies = [
"lexical-core",
"memchr",
"version_check 0.9.4",
]
[[package]]
name = "nom"
version = "7.1.3"
@ -4661,29 +4591,6 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
name = "openbook-v2"
version = "0.1.0"
source = "git+https://github.com/openbook-dex/openbook-v2?tag=v0.2.7#b855221e2e1fd8b907f0633e6c0be3ea9919267f"
dependencies = [
"anchor-lang",
"anchor-spl",
"arrayref",
"bytemuck",
"default-env",
"derivative",
"fixed",
"itertools 0.10.5",
"num_enum 0.5.11",
"pyth-sdk-solana",
"solana-program",
"solana-sdk",
"solana-security-txt",
"static_assertions",
"switchboard-program",
"switchboard-solana",
]
[[package]]
name = "openssl"
version = "0.10.64"
@ -5366,37 +5273,6 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "pyth-sdk"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e7aeef4d5f0a9c98ff5af2ddd84a8b89919c512188305b497a9eb9afa97a949"
dependencies = [
"borsh 0.10.3",
"borsh-derive 0.10.3",
"getrandom 0.2.14",
"hex",
"schemars",
"serde",
]
[[package]]
name = "pyth-sdk-solana"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f913de6eb29d8def199af3beaee645e84c5281327d58777eff3fdd9f1d37105"
dependencies = [
"borsh 0.10.3",
"borsh-derive 0.10.3",
"bytemuck",
"num-derive 0.3.3",
"num-traits",
"pyth-sdk",
"serde",
"solana-program",
"thiserror",
]
[[package]]
name = "qstring"
version = "0.7.2"
@ -5452,15 +5328,6 @@ dependencies = [
"thiserror",
]
[[package]]
name = "quick-protobuf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ca6639207ac869e31cca06b8adbc7676278f22b321e51115766009b4f192dbb"
dependencies = [
"byteorder",
]
[[package]]
name = "quinn"
version = "0.10.2"
@ -6113,7 +5980,7 @@ version = "1.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c4216490d5a413bc6d10fa4742bd7d4955941d062c0ef873141d6b0e7b30fd"
dependencies = [
"arrayvec 0.7.4",
"arrayvec",
"borsh 0.10.3",
"bytes 1.6.0",
"num-traits",
@ -6123,16 +5990,6 @@ dependencies = [
"serde_json",
]
[[package]]
name = "rust_decimal_macros"
version = "1.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69deb21b04afa2c06038f75bbbb5670a320e62ee005d91a00cf13fbf20161886"
dependencies = [
"quote 1.0.35",
"rust_decimal",
]
[[package]]
name = "rustc-demangle"
version = "0.1.23"
@ -6169,7 +6026,7 @@ version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632"
dependencies = [
"nom 7.1.3",
"nom",
]
[[package]]
@ -6457,30 +6314,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "schemars"
version = "0.8.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f55c82c700538496bdc329bb4918a81f87cc8888811bd123cf325a0f2f8d309"
dependencies = [
"dyn-clone",
"schemars_derive",
"serde",
"serde_json",
]
[[package]]
name = "schemars_derive"
version = "0.8.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83263746fe5e32097f06356968a077f96089739c927a61450efa069905eec108"
dependencies = [
"proc-macro2 1.0.86",
"quote 1.0.35",
"serde_derive_internals",
"syn 2.0.58",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
@ -6602,26 +6435,6 @@ dependencies = [
"syn 2.0.58",
]
[[package]]
name = "serde_derive_internals"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
dependencies = [
"proc-macro2 1.0.86",
"quote 1.0.35",
"syn 2.0.58",
]
[[package]]
name = "serde_fmt"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4"
dependencies = [
"serde",
]
[[package]]
name = "serde_json"
version = "1.0.120"
@ -6732,15 +6545,6 @@ dependencies = [
"tracing",
]
[[package]]
name = "sgx-quote"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1640577af7b81d10db340c4b31006b77972e3918f351eec4e65c389c8b58e21"
dependencies = [
"nom 5.1.3",
]
[[package]]
name = "sha-1"
version = "0.8.2"
@ -8583,191 +8387,6 @@ version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "superslice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
[[package]]
name = "sval"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53eb957fbc79a55306d5d25d87daf3627bc3800681491cda0709eef36c748bfe"
[[package]]
name = "sval_buffer"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96e860aef60e9cbf37888d4953a13445abf523c534640d1f6174d310917c410d"
dependencies = [
"sval",
"sval_ref",
]
[[package]]
name = "sval_dynamic"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea3f2b07929a1127d204ed7cb3905049381708245727680e9139dac317ed556f"
dependencies = [
"sval",
]
[[package]]
name = "sval_fmt"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4e188677497de274a1367c4bda15bd2296de4070d91729aac8f0a09c1abf64d"
dependencies = [
"itoa",
"ryu",
"sval",
]
[[package]]
name = "sval_json"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32f456c07dae652744781f2245d5e3b78e6a9ebad70790ac11eb15dbdbce5282"
dependencies = [
"itoa",
"ryu",
"sval",
]
[[package]]
name = "sval_nested"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "886feb24709f0476baaebbf9ac10671a50163caa7e439d7a7beb7f6d81d0a6fb"
dependencies = [
"sval",
"sval_buffer",
"sval_ref",
]
[[package]]
name = "sval_ref"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be2e7fc517d778f44f8cb64140afa36010999565528d48985f55e64d45f369ce"
dependencies = [
"sval",
]
[[package]]
name = "sval_serde"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79bf66549a997ff35cd2114a27ac4b0c2843280f2cfa84b240d169ecaa0add46"
dependencies = [
"serde",
"sval",
"sval_nested",
]
[[package]]
name = "switchboard-common"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c96fe58be35530580b729fa5d846661c89a007982527f4ff0ca6010168564159"
dependencies = [
"async-trait",
"base64 0.21.7",
"envy",
"futures 0.3.30",
"getrandom 0.2.14",
"hex",
"log 0.4.21",
"serde",
"serde_json",
"sgx-quote",
"sha2 0.10.8",
"sha3 0.10.8",
]
[[package]]
name = "switchboard-program"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534d4b2d45907427fc8d2cd151465cfaee3709c4742491734bc34e5a458ebd09"
dependencies = [
"bincode",
"borsh 0.9.3",
"bytemuck",
"byteorder",
"quick-protobuf",
"solana-program",
"switchboard-protos",
"switchboard-utils",
]
[[package]]
name = "switchboard-protos"
version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e2d89875ff72d12ea7918d6ccd82d1ac5eab54b3a9d1bd7356fa6905801aa72"
dependencies = [
"bincode",
"borsh 0.9.3",
"byteorder",
"quick-protobuf",
]
[[package]]
name = "switchboard-solana"
version = "0.29.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35443cb745b071876be79b719a9314e4f354e259807539224ffc6bf1e0854f3d"
dependencies = [
"anchor-client",
"anchor-lang",
"anchor-spl",
"arc-swap",
"base64 0.21.7",
"bincode",
"bytemuck",
"chrono",
"cron",
"dashmap 5.5.3",
"futures 0.3.30",
"hex",
"kv-log-macro",
"log 0.4.21",
"rust_decimal",
"serde",
"serde_json",
"sgx-quote",
"sha2 0.10.8",
"solana-account-decoder",
"solana-address-lookup-table-program",
"solana-client",
"solana-program",
"superslice",
"switchboard-common",
"tokio",
"tokio-util 0.7.10",
"url 2.5.0",
]
[[package]]
name = "switchboard-utils"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac1d68193aa1669e34d16087db0f96e6597d2f78868378aabc1387b8b29172e"
dependencies = [
"bincode",
"borsh 0.9.3",
"bytemuck",
"byteorder",
"quick-protobuf",
"rust_decimal",
"rust_decimal_macros",
"solana-program",
"switchboard-protos",
]
[[package]]
name = "symlink"
version = "0.1.0"
@ -9358,7 +8977,6 @@ dependencies = [
"futures-core",
"futures-sink",
"pin-project-lite",
"slab",
"tokio",
"tracing",
]
@ -9843,42 +9461,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "value-bag"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8"
dependencies = [
"value-bag-serde1",
"value-bag-sval2",
]
[[package]]
name = "value-bag-serde1"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc35703541cbccb5278ef7b589d79439fc808ff0b5867195a3230f9a47421d39"
dependencies = [
"erased-serde",
"serde",
"serde_fmt",
]
[[package]]
name = "value-bag-sval2"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "285b43c29d0b4c0e65aad24561baee67a1b69dc9be9375d4a85138cbf556f7f8"
dependencies = [
"sval",
"sval_buffer",
"sval_dynamic",
"sval_fmt",
"sval_json",
"sval_ref",
"sval_serde",
]
[[package]]
name = "vcpkg"
version = "0.2.15"
@ -10454,7 +10036,7 @@ dependencies = [
"data-encoding",
"der-parser",
"lazy_static",
"nom 7.1.3",
"nom",
"oid-registry",
"rusticata-macros",
"thiserror",

View File

@ -20,7 +20,6 @@ yellowstone-grpc-proto = { version = "1.14.0", git = "https://github.com/blockwo
reqwest = { version = "0.11.27", features = ["json"] }
whirlpools-client = { git = "https://github.com/blockworks-foundation/whirlpools-client/", features = ["no-entrypoint"] }
openbook-v2 = { git = "https://github.com/openbook-dex/openbook-v2", tag = "v0.2.7", features = ["no-entrypoint", "client"] }
raydium-cp-swap = { git = "https://github.com/raydium-io/raydium-cp-swap/", features = ["no-entrypoint", "client"] }
stable-swap = { version = "1.8.1", features = ["no-entrypoint", "client"] }
stable-swap-client = { version = "1.8.1" }

View File

@ -80,7 +80,7 @@ dex-saber = { path = "../../lib/dex-saber/", version = "0.0.1" }
dex-infinity = { path = "../../lib/dex-infinity/", version = "0.0.1" }
dex-openbook-v2 = { path = "../../lib/dex-openbook-v2/", version = "0.0.1" }
dex-invariant = { path = "../../lib/dex-invariant", version = "0.0.1" }
dex-gobbler = { path = "../../lib/dex-gobbler", version = "0.0.1" }
router-config-lib = { path = "../../lib/router-config-lib" }
router-feed-lib = { path = "../../lib/router-feed-lib" }
spl-associated-token-account = { version = "1.0.5",features = ["no-entrypoint"] }

View File

@ -298,6 +298,14 @@ async fn main() -> anyhow::Result<()> {
true,
&vec![]
),
dex::generic::build_dex!(
dex_gobbler::GobblerDex::initialize(&mut router_rpc, HashMap::new()).await?,
&mango_data,
config.gobbler.enabled,
config.gobbler.take_all_mints,
config.gobbler.add_mango_tokens,
&config.gobbler.mints
),
dex::generic::build_dex!(
dex_invariant::InvariantDex::initialize(&mut router_rpc, HashMap::new()).await?,
&mango_data,

View File

@ -0,0 +1,35 @@
[package]
name = "dex-gobbler"
version = "0.0.1"
edition = "2021"
[lib]
doctest = false
[dependencies]
router-lib = { path = "../router-lib", version = "0.0.1" }
router-feed-lib = { path = "../router-feed-lib", version = "0.1" }
solana-account-decoder = "1.17"
solana-client = { workspace = true }
solana-sdk = { workspace = true }
solana-logger = "1.17"
solana-program = "1.17"
solana-program-test = "1.17"
anchor-lang = "0.29.0"
anchor-client = "0.29.0"
anchor-spl = "0.29.0"
anyhow = "1.0.86"
itertools = "0.10.5"
async-trait = "0.1.79"
chrono = "0.4.38"
sha2 = "0.10.8"
tracing = "0.1.40"
spl-associated-token-account = "1.0.5"
serde = "1.0"
serde_derive = "1.0"
mango-feeds-connector = { workspace = true }
# raydium-cp
gobblerdev = {version = "0.1.142" }
[dev-dependencies]
router-test-lib = { path = "../router-test-lib", version = "0.1" }

198
lib/dex-gobbler/src/edge.rs Normal file
View File

@ -0,0 +1,198 @@
use anchor_lang::Id;
use anchor_spl::token::Token;
use anchor_spl::token_2022::spl_token_2022::extension::transfer_fee::TransferFeeConfig;
use anchor_spl::token_2022::spl_token_2022::extension::{
BaseStateWithExtensions, StateWithExtensions,
};
use anyhow::anyhow;
use anchor_spl::token_2022::spl_token_2022::state::Mint;
use mango_feeds_connector::chain_data::AccountData;
use gobblerdev::curve::{CurveCalculator, TradeDirection};
use gobblerdev::states::{AmmConfig, PoolState, PoolStatusBitIndex};
use solana_program::clock::Clock;
use solana_program::pubkey::Pubkey;
use solana_program::sysvar::Sysvar;
use solana_sdk::account::ReadableAccount;
use std::any::Any;
use std::panic;
use router_lib::dex::{DexEdge, DexEdgeIdentifier};
pub struct GobblerEdgeIdentifier {
pub pool: Pubkey,
pub mint_a: Pubkey,
pub mint_b: Pubkey,
pub is_a_to_b: bool,
}
impl DexEdgeIdentifier for GobblerEdgeIdentifier {
fn key(&self) -> Pubkey {
self.pool
}
fn desc(&self) -> String {
format!("Gobbler_{}", self.pool)
}
fn input_mint(&self) -> Pubkey {
self.mint_a
}
fn output_mint(&self) -> Pubkey {
self.mint_b
}
fn accounts_needed(&self) -> usize {
11
}
fn as_any(&self) -> &dyn Any {
self
}
}
pub struct GobblerEdge {
pub pool: PoolState,
pub config: AmmConfig,
pub vault_0_amount: u64,
pub vault_1_amount: u64,
pub mint_0: Option<TransferFeeConfig>,
pub mint_1: Option<TransferFeeConfig>,
}
impl DexEdge for GobblerEdge {
fn as_any(&self) -> &dyn Any {
self
}
}
pub(crate) fn get_transfer_config(
mint_account: &AccountData,
) -> anyhow::Result<Option<TransferFeeConfig>> {
if *mint_account.account.owner() == Token::id() {
return Ok(None);
}
let mint = StateWithExtensions::<Mint>::unpack(mint_account.account.data())?;
if let Ok(transfer_fee_config) = mint.get_extension::<TransferFeeConfig>() {
Ok(Some(*transfer_fee_config))
} else {
Ok(None)
}
}
#[allow(clippy::too_many_arguments)]
pub fn swap_base_input(
pool: &PoolState,
amm_config: &AmmConfig,
input_vault_key: Pubkey,
input_vault_amount: u64,
input_mint: &Option<TransferFeeConfig>,
output_vault_key: Pubkey,
output_vault_amount: u64,
output_mint: &Option<TransferFeeConfig>,
amount_in: u64,
) -> anyhow::Result<(u64, u64, u64)> {
let (total_input_token_amount, total_output_token_amount) = if input_vault_key == pool.token_0_vault {
vault_amount_without_fee(pool, input_vault_amount, output_vault_amount)?
} else {
let (out, inp) = vault_amount_without_fee(pool, output_vault_amount, input_vault_amount)?;
(inp, out)
};
let (input_token_creator_rate, input_token_lp_rate) = if input_vault_key == pool.token_0_vault {
(amm_config.creator_fee, amm_config.token_0_lp_rate)
} else {
(amm_config.creator_fee, amm_config.token_1_lp_rate)
};
let protocol_fee = amm_config.protocol_fee;
let swap_result = CurveCalculator::swap_base_input(
amount_in.into(),
total_input_token_amount.into(),
total_output_token_amount.into(),
(protocol_fee + input_token_creator_rate + input_token_lp_rate) as u128,
protocol_fee,
input_token_creator_rate,
).ok_or_else(|| anyhow!("Swap calculation failed"))?;
let amount_received = swap_result.destination_amount_swapped;
Ok((
amount_in,
amount_received.try_into().map_err(|e| anyhow!("Failed to convert amount_received: {}", e))?,
swap_result.total_fees.try_into().map_err(|e| anyhow!("Failed to convert fees: {}", e))?,
))
}
#[allow(clippy::too_many_arguments)]
pub fn swap_base_output(
pool: &PoolState,
amm_config: &AmmConfig,
input_vault_key: Pubkey,
input_vault_amount: u64,
_input_mint: &Option<TransferFeeConfig>,
output_vault_key: Pubkey,
output_vault_amount: u64,
_output_mint: &Option<TransferFeeConfig>,
amount_out: u64,
) -> anyhow::Result<(u64, u64, u64)> {
let (total_input_token_amount, total_output_token_amount) = if input_vault_key == pool.token_0_vault {
vault_amount_without_fee(pool, input_vault_amount, output_vault_amount)?
} else {
let (out, inp) = vault_amount_without_fee(pool, output_vault_amount, input_vault_amount)?;
(inp, out)
};
let (input_token_creator_rate, input_token_lp_rate) = if input_vault_key == pool.token_0_vault {
(amm_config.creator_fee, amm_config.token_0_lp_rate)
} else {
(amm_config.creator_fee, amm_config.token_1_lp_rate)
};
let protocol_fee = amm_config.protocol_fee;
let swap_result = CurveCalculator::swap_base_output(
amount_out.into(),
total_input_token_amount.into(),
total_output_token_amount.into(),
(protocol_fee + input_token_creator_rate + input_token_lp_rate) as u128,
protocol_fee,
input_token_creator_rate,
).ok_or_else(|| anyhow!("Swap calculation failed"))?;
Ok((
swap_result.source_amount_swapped.try_into().map_err(|e| anyhow!("Failed to convert amount_in: {}", e))?,
amount_out,
swap_result.total_fees.try_into().map_err(|e| anyhow!("Failed to convert fees: {}", e))?,
))
}
pub fn get_transfer_fee(
mint_info: &Option<TransferFeeConfig>,
pre_fee_amount: u64,
) -> anchor_lang::Result<u64> {
let fee = if let Some(transfer_fee_config) = mint_info {
transfer_fee_config
.calculate_epoch_fee(Clock::get()?.epoch, pre_fee_amount)
.unwrap()
} else {
0
};
Ok(fee)
}
pub fn vault_amount_without_fee(
pool: &PoolState,
vault_0: u64,
vault_1: u64,
) -> anyhow::Result<(u64, u64)> {
Ok((
vault_0
.checked_sub(pool.protocol_fees_token_0 + pool.fund_fees_token_0)
.ok_or(anyhow::format_err!("invalid sub"))?,
vault_1
.checked_sub(pool.protocol_fees_token_1 + pool.fund_fees_token_1)
.ok_or(anyhow::format_err!("invalid sub"))?,
))
}

View File

@ -0,0 +1,409 @@
use crate::edge::{swap_base_input, swap_base_output, GobblerEdge, GobblerEdgeIdentifier};
use crate::gobbler_ix_builder;
use anchor_lang::{AccountDeserialize, Discriminator, Id};
use anchor_spl::token::spl_token::state::AccountState;
use anchor_spl::token::{spl_token, Token};
use anchor_spl::token_2022::spl_token_2022;
use anyhow::Context;
use async_trait::async_trait;
use itertools::Itertools;
use gobblerdev::program::Gobbler;
use gobblerdev::states::{AmmConfig, PoolState, PoolStatusBitIndex};
use router_feed_lib::router_rpc_client::{RouterRpcClient, RouterRpcClientTrait};
use router_lib::dex::{
AccountProviderView, DexEdge, DexEdgeIdentifier, DexInterface, DexSubscriptionMode,
MixedDexSubscription, Quote, SwapInstruction,
};
use router_lib::utils;
use solana_account_decoder::UiAccountEncoding;
use solana_client::rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig};
use solana_client::rpc_filter::{Memcmp, RpcFilterType};
use solana_program::program_pack::Pack;
use solana_program::pubkey::Pubkey;
use solana_sdk::account::ReadableAccount;
use solana_sdk::clock::Clock;
use solana_sdk::commitment_config::CommitmentConfig;
use solana_sdk::sysvar::SysvarId;
use std::collections::{HashMap, HashSet};
use std::str::FromStr;
use std::sync::Arc;
use std::u64;
pub struct GobblerDex {
pub edges: HashMap<Pubkey, Vec<Arc<dyn DexEdgeIdentifier>>>,
pub needed_accounts: HashSet<Pubkey>,
}
#[async_trait]
impl DexInterface for GobblerDex {
async fn initialize(
rpc: &mut RouterRpcClient,
_options: HashMap<String, String>,
) -> anyhow::Result<Arc<dyn DexInterface>>
where
Self: Sized,
{
let pools =
fetch_raydium_account::<PoolState>(rpc, gobblerdev::id(), std::mem::size_of::<PoolState>() + 8).await?;
let vaults = pools
.iter()
.flat_map(|x| [x.1.token_0_vault, x.1.token_1_vault])
.collect::<HashSet<_>>();
let vaults = rpc.get_multiple_accounts(&vaults).await?;
let banned_vaults = vaults
.iter()
.filter(|x| {
x.1.owner == Token::id()
&& spl_token::state::Account::unpack(x.1.data()).unwrap().state
== AccountState::Frozen
})
.map(|x| x.0)
.collect::<HashSet<_>>();
let edge_pairs = pools
.iter()
.map(|(pool_pk, pool)| {
(
Arc::new(GobblerEdgeIdentifier {
pool: *pool_pk,
mint_a: pool.token_0_mint,
mint_b: pool.token_1_mint,
is_a_to_b: true,
}),
Arc::new(GobblerEdgeIdentifier {
pool: *pool_pk,
mint_a: pool.token_1_mint,
mint_b: pool.token_0_mint,
is_a_to_b: false,
}),
)
})
.collect_vec();
let mut needed_accounts = HashSet::new();
let edges_per_pk = {
let mut map = HashMap::new();
for ((pool_pk, pool), (edge_a_to_b, edge_b_to_a)) in pools.iter().zip(edge_pairs.iter())
{
let entry = vec![
edge_a_to_b.clone() as Arc<dyn DexEdgeIdentifier>,
edge_b_to_a.clone(),
];
utils::insert_or_extend(&mut map, pool_pk, &entry);
utils::insert_or_extend(&mut map, &pool.amm_config, &entry);
utils::insert_or_extend(&mut map, &pool.token_0_vault, &entry);
utils::insert_or_extend(&mut map, &pool.token_1_vault, &entry);
needed_accounts.insert(*pool_pk);
needed_accounts.insert(pool.amm_config);
needed_accounts.insert(pool.token_0_vault);
needed_accounts.insert(pool.token_1_vault);
}
map
};
Ok(Arc::new(GobblerDex {
edges: edges_per_pk,
needed_accounts,
}))
}
fn name(&self) -> String {
"Gobbler".to_string()
}
fn subscription_mode(&self) -> DexSubscriptionMode {
DexSubscriptionMode::Mixed(MixedDexSubscription {
accounts: Default::default(),
programs: HashSet::from([gobblerdev::id()]),
token_accounts_for_owner: HashSet::from([Pubkey::from_str(
"9pR79Lqe6wDNjag3v8MeVYUostoXjY2ognTydor6AtEZ",
)
.unwrap()]),
})
}
fn program_ids(&self) -> HashSet<Pubkey> {
[gobblerdev::id()].into_iter().collect()
}
fn edges_per_pk(&self) -> HashMap<Pubkey, Vec<Arc<dyn DexEdgeIdentifier>>> {
self.edges.clone()
}
fn load(
&self,
id: &Arc<dyn DexEdgeIdentifier>,
chain_data: &AccountProviderView,
) -> anyhow::Result<Arc<dyn DexEdge>> {
let id = id
.as_any()
.downcast_ref::<GobblerEdgeIdentifier>()
.unwrap();
let pool_account = chain_data.account(&id.pool)?;
let pool = try_deserialize_unchecked_from_bytes_zc(&pool_account.account.data())?;
let config_account = chain_data.account(&pool.amm_config)?;
let config = AmmConfig::try_deserialize(&mut config_account.account.data())?;
let vault_0_account = chain_data.account(&pool.token_0_vault)?;
let vault_0 = spl_token_2022::state::Account::unpack(vault_0_account.account.data())?;
let vault_1_account = chain_data.account(&pool.token_1_vault)?;
let vault_1 = spl_token_2022::state::Account::unpack(vault_1_account.account.data())?;
let transfer_0_fee = None;
let transfer_1_fee = None;
Ok(Arc::new(GobblerEdge {
pool,
config,
vault_0_amount: vault_0.amount,
vault_1_amount: vault_1.amount,
mint_0: transfer_0_fee,
mint_1: transfer_1_fee,
}))
}
fn quote(
&self,
id: &Arc<dyn DexEdgeIdentifier>,
edge: &Arc<dyn DexEdge>,
chain_data: &AccountProviderView,
in_amount: u64,
) -> anyhow::Result<Quote> {
let id = id
.as_any()
.downcast_ref::<GobblerEdgeIdentifier>()
.unwrap();
let edge = edge.as_any().downcast_ref::<GobblerEdge>().unwrap();
if !edge.pool.get_status_by_bit(PoolStatusBitIndex::Swap) {
return Ok(Quote {
in_amount: 0,
out_amount: 0,
fee_amount: 0,
fee_mint: edge.pool.token_0_mint,
});
}
let clock = chain_data.account(&Clock::id()).context("read clock")?;
let now_ts = clock.account.deserialize_data::<Clock>()?.unix_timestamp as u64;
if edge.pool.open_time > now_ts {
return Ok(Quote {
in_amount: 0,
out_amount: 0,
fee_amount: 0,
fee_mint: edge.pool.token_0_mint,
});
}
let quote = if id.is_a_to_b {
let result = swap_base_input(
&edge.pool,
&edge.config,
edge.pool.token_0_vault,
edge.vault_0_amount,
&edge.mint_0,
edge.pool.token_1_vault,
edge.vault_1_amount,
&edge.mint_1,
in_amount,
)?;
Quote {
in_amount: result.0,
out_amount: result.1,
fee_amount: result.2,
fee_mint: edge.pool.token_0_mint,
}
} else {
let result = swap_base_input(
&edge.pool,
&edge.config,
edge.pool.token_1_vault,
edge.vault_1_amount,
&edge.mint_1,
edge.pool.token_0_vault,
edge.vault_0_amount,
&edge.mint_0,
in_amount,
)?;
Quote {
in_amount: result.0,
out_amount: result.1,
fee_amount: result.2,
fee_mint: edge.pool.token_1_mint,
}
};
Ok(quote)
}
fn build_swap_ix(
&self,
id: &Arc<dyn DexEdgeIdentifier>,
chain_data: &AccountProviderView,
wallet_pk: &Pubkey,
in_amount: u64,
out_amount: u64,
max_slippage_bps: i32,
) -> anyhow::Result<SwapInstruction> {
let id = id
.as_any()
.downcast_ref::<GobblerEdgeIdentifier>()
.unwrap();
gobbler_ix_builder::build_swap_ix(
id,
chain_data,
wallet_pk,
in_amount,
out_amount,
max_slippage_bps,
)
}
fn supports_exact_out(&self, _id: &Arc<dyn DexEdgeIdentifier>) -> bool {
true
}
fn quote_exact_out(
&self,
id: &Arc<dyn DexEdgeIdentifier>,
edge: &Arc<dyn DexEdge>,
chain_data: &AccountProviderView,
out_amount: u64,
) -> anyhow::Result<Quote> {
let id = id
.as_any()
.downcast_ref::<GobblerEdgeIdentifier>()
.unwrap();
let edge = edge.as_any().downcast_ref::<GobblerEdge>().unwrap();
if !edge.pool.get_status_by_bit(PoolStatusBitIndex::Swap) {
return Ok(Quote {
in_amount: u64::MAX,
out_amount: 0,
fee_amount: 0,
fee_mint: edge.pool.token_0_mint,
});
}
let clock = chain_data.account(&Clock::id()).context("read clock")?;
let now_ts = clock.account.deserialize_data::<Clock>()?.unix_timestamp as u64;
if edge.pool.open_time > now_ts {
return Ok(Quote {
in_amount: u64::MAX,
out_amount: 0,
fee_amount: 0,
fee_mint: edge.pool.token_0_mint,
});
}
let quote = if id.is_a_to_b {
let result = swap_base_output(
&edge.pool,
&edge.config,
edge.pool.token_0_vault,
edge.vault_0_amount,
&edge.mint_0,
edge.pool.token_1_vault,
edge.vault_1_amount,
&edge.mint_1,
out_amount,
)?;
Quote {
in_amount: result.0,
out_amount: result.1,
fee_amount: result.2,
fee_mint: edge.pool.token_0_mint,
}
} else {
let result = swap_base_output(
&edge.pool,
&edge.config,
edge.pool.token_1_vault,
edge.vault_1_amount,
&edge.mint_1,
edge.pool.token_0_vault,
edge.vault_0_amount,
&edge.mint_0,
out_amount,
)?;
Quote {
in_amount: result.0,
out_amount: result.1,
fee_amount: result.2,
fee_mint: edge.pool.token_1_mint,
}
};
Ok(quote)
}
}
pub fn try_deserialize_unchecked_from_bytes<T: AccountDeserialize>(data: &[u8]) -> Result<T, anyhow::Error> {
T::try_deserialize(&mut data.as_ref())
.map_err(|e| anyhow::anyhow!("Failed to deserialize account: {}", e))
}
pub fn try_deserialize_unchecked_from_bytes_zc(input: &[u8]) -> Result<PoolState, anyhow::Error> {
if input.is_empty() {
return Err(anyhow::anyhow!("Input data is empty"));
}
if input.len() < 8 {
return Err(anyhow::anyhow!("Input data is too short"));
}
let pool_state = unsafe {
let pool_state_ptr = input[8..].as_ptr() as *const PoolState;
std::ptr::read_unaligned(pool_state_ptr)
};
Ok(pool_state)
}
async fn fetch_raydium_account<T: Discriminator + AccountDeserialize>(
rpc: &mut RouterRpcClient,
program_id: Pubkey,
len: usize,
) -> anyhow::Result<Vec<(Pubkey, PoolState)>> {
let config = RpcProgramAccountsConfig {
filters: Some(vec![
RpcFilterType::Memcmp(Memcmp::new_raw_bytes(0, T::DISCRIMINATOR.to_vec())),
]),
account_config: RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Base64),
commitment: Some(CommitmentConfig::finalized()),
..Default::default()
},
..Default::default()
};
let snapshot = rpc
.get_program_accounts_with_config(&program_id, config)
.await?;
let result = snapshot
.iter()
.filter_map(|account| {
let mut data = account.data.as_slice();
if data.len() < len {
return None;
}
if &data[..8] != T::DISCRIMINATOR {
return None;
}
let maybe = try_deserialize_unchecked_from_bytes_zc(&data);
if let Ok(pool) = maybe {
Some((account.pubkey, pool))
} else {
None
}
})
.collect::<Vec<_>>();
Ok(result)
}

View File

@ -0,0 +1,103 @@
use crate::edge::GobblerEdgeIdentifier;
use anchor_lang::{AccountDeserialize, Id, InstructionData, ToAccountMetas};
use anchor_spl::associated_token::get_associated_token_address;
use gobblerdev::program::Gobbler;
use gobblerdev::states::PoolState;
use gobblerdev::AUTH_SEED;
use router_lib::dex::{AccountProviderView, SwapInstruction};
use solana_program::instruction::Instruction;
use solana_program::pubkey::Pubkey;
use solana_sdk::account::ReadableAccount;
pub fn try_deserialize_unchecked_from_bytes_zc(input: &[u8]) -> Result<PoolState, anyhow::Error> {
if input.is_empty() {
return Err(anyhow::anyhow!("Input data is empty"));
}
if input.len() < 8 {
return Err(anyhow::anyhow!("Input data is too short"));
}
let pool_state = unsafe {
let pool_state_ptr = input[8..].as_ptr() as *const PoolState;
std::ptr::read_unaligned(pool_state_ptr)
};
Ok(pool_state)
}
pub fn build_swap_ix(
id: &GobblerEdgeIdentifier,
chain_data: &AccountProviderView,
wallet_pk: &Pubkey,
in_amount: u64,
out_amount: u64,
max_slippage_bps: i32,
) -> anyhow::Result<SwapInstruction> {
let pool_account = chain_data.account(&id.pool)?;
let mut pool = PoolState::default();
let pm = try_deserialize_unchecked_from_bytes_zc(&pool_account.account.data());
if pm.is_ok() {
pool = pm?;
}
let amount = in_amount;
let other_amount_threshold =
((out_amount as f64 * (10_000f64 - max_slippage_bps as f64)) / 10_000f64).floor() as u64;
let (input_token_mint, output_token_mint) = if id.is_a_to_b {
(pool.token_0_mint, pool.token_1_mint)
} else {
(pool.token_1_mint, pool.token_0_mint)
};
let (input_token_program, output_token_program) = if id.is_a_to_b {
(pool.token_0_program, pool.token_1_program)
} else {
(pool.token_1_program, pool.token_0_program)
};
let (input_vault, output_vault) = if id.is_a_to_b {
(pool.token_0_vault, pool.token_1_vault)
} else {
(pool.token_1_vault, pool.token_0_vault)
};
let (input_token_account, output_token_account) = (
get_associated_token_address(wallet_pk, &input_token_mint),
get_associated_token_address(wallet_pk, &output_token_mint),
);
let instruction = gobblerdev::instruction::SwapBaseInput {
amount_in: amount,
minimum_amount_out: other_amount_threshold,
};
let (authority, __bump) =
Pubkey::find_program_address(&[AUTH_SEED.as_bytes()], &gobblerdev::id());
let accounts = gobblerdev::accounts::Swap {
payer: *wallet_pk,
authority,
amm_config: pool.amm_config,
pool_state: id.pool,
input_token_account,
output_token_account,
input_vault,
output_vault,
input_token_program,
output_token_program,
input_token_mint,
output_token_mint,
observation_state: pool.observation_key,
};
let result = SwapInstruction {
instruction: Instruction {
program_id: gobblerdev::id(),
accounts: accounts.to_account_metas(None),
data: instruction.data(),
},
out_pubkey: output_token_account,
out_mint: output_token_mint,
in_amount_offset: 8,
cu_estimate: Some(40_000),
};
Ok(result)
}

View File

@ -0,0 +1,5 @@
mod edge;
mod gobbler;
mod gobbler_ix_builder;
pub use crate::gobbler::GobblerDex;

View File

@ -0,0 +1,43 @@
use std::collections::HashMap;
use std::env;
use solana_program_test::tokio;
use router_lib::dex::DexInterface;
use router_lib::test_tools::{generate_dex_rpc_dump, rpc};
#[tokio::test]
async fn test_dump_input_data_raydium_cp() -> anyhow::Result<()> {
let options = HashMap::from([]);
if router_test_lib::config_should_dump_mainnet_data() {
raydium_cp_step_1(&options).await?;
}
raydium_cp_step_2(&options).await?;
Ok(())
}
async fn raydium_cp_step_1(options: &HashMap<String, String>) -> anyhow::Result<()> {
let rpc_url = env::var("RPC_HTTP_URL")?;
let (mut rpc_client, chain_data) = rpc::rpc_dumper_client(rpc_url, "raydium_cp_dump.lz4");
let dex = dex_gobbler::GobblerDex::initialize(&mut rpc_client, options.clone()).await?;
generate_dex_rpc_dump::run_dump_mainnet_data(dex, rpc_client, chain_data).await?;
Ok(())
}
async fn raydium_cp_step_2(options: &HashMap<String, String>) -> anyhow::Result<()> {
// Replay
let (mut rpc_client, chain_data) = rpc::rpc_replayer_client("raydium_cp_dump.lz4");
let dex = dex_gobbler::GobblerDex::initialize(&mut rpc_client, options.clone()).await?;
generate_dex_rpc_dump::run_dump_swap_ix("gobblerdev.lz4", dex, chain_data).await?;
Ok(())
}

View File

@ -43,6 +43,7 @@ pub struct Config {
pub saber: DexConfig,
pub invariant: DexConfig,
pub infinity: InfinityConfig,
pub gobbler: DexConfig,
pub safety_checks: Option<SafetyCheckConfig>,
pub hot_mints: Option<HotMintsConfig>,
pub debug_config: Option<DebugConfig>,