solana: усилить проверку Pyth oracle в shine_payments
This commit is contained in:
parent
5981d3f871
commit
9ca469a075
@ -1,2 +1,2 @@
|
|||||||
client.version=1.2.149
|
client.version=1.2.150
|
||||||
server.version=1.2.141
|
server.version=1.2.142
|
||||||
|
|||||||
378
shine-solana/shine/Cargo.lock
generated
378
shine-solana/shine/Cargo.lock
generated
@ -14,6 +14,188 @@ dependencies = [
|
|||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-attribute-access-control"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f70fd141a4d18adf11253026b32504f885447048c7494faf5fa83b01af9c0cf"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-syn",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-attribute-account"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "715a261c57c7679581e06f07a74fa2af874ac30f86bd8ea07cca4a7e5388a064"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-syn",
|
||||||
|
"bs58",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-attribute-constant"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "730d6df8ae120321c5c25e0779e61789e4b70dc8297102248902022f286102e4"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-syn",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-attribute-error"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "27e6e449cc3a37b2880b74dcafb8e5a17b954c0e58e376432d7adc646fb333ef"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-syn",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-attribute-event"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7710e4c54adf485affcd9be9adec5ef8846d9c71d7f31e16ba86ff9fc1dd49f"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-syn",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-attribute-program"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05ecfd49b2aeadeb32f35262230db402abed76ce87e27562b34f61318b2ec83c"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-lang-idl",
|
||||||
|
"anchor-syn",
|
||||||
|
"anyhow",
|
||||||
|
"bs58",
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde_json",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-derive-accounts"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "be89d160793a88495af462a7010b3978e48e30a630c91de47ce2c1d3cb7a6149"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-syn",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-derive-serde"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "abc6ee78acb7bfe0c2dd2abc677aaa4789c0281a0c0ef01dbf6fe85e0fd9e6e4"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-syn",
|
||||||
|
"borsh-derive-internal",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-derive-space"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "134a01c0703f6fd355a0e472c033f6f3e41fac1ef6e370b20c50f4c8d022cea7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-lang"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6bab117055905e930f762c196e08f861f8dfe7241b92cee46677a3b15561a0a"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-attribute-access-control",
|
||||||
|
"anchor-attribute-account",
|
||||||
|
"anchor-attribute-constant",
|
||||||
|
"anchor-attribute-error",
|
||||||
|
"anchor-attribute-event",
|
||||||
|
"anchor-attribute-program",
|
||||||
|
"anchor-derive-accounts",
|
||||||
|
"anchor-derive-serde",
|
||||||
|
"anchor-derive-space",
|
||||||
|
"base64 0.21.7",
|
||||||
|
"bincode",
|
||||||
|
"borsh 0.10.4",
|
||||||
|
"bytemuck",
|
||||||
|
"solana-program",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-lang-idl"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32e8599d21995f68e296265aa5ab0c3cef582fd58afec014d01bd0bce18a4418"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-lang-idl-spec",
|
||||||
|
"anyhow",
|
||||||
|
"heck",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha2 0.10.9",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-lang-idl-spec"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bdf143115440fe621bdac3a29a1f7472e09f6cd82b2aa569429a0c13f103838"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anchor-syn"
|
||||||
|
version = "0.31.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5dc7a6d90cc643df0ed2744862cdf180587d1e5d28936538c18fc8908489ed67"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"bs58",
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha2 0.10.9",
|
||||||
|
"syn 1.0.109",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.102"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -38,6 +220,12 @@ version = "0.12.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
|
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.21.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.22.1"
|
version = "0.22.1"
|
||||||
@ -189,6 +377,9 @@ name = "bytemuck"
|
|||||||
version = "1.23.0"
|
version = "1.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c"
|
checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck_derive",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck_derive"
|
name = "bytemuck_derive"
|
||||||
@ -201,6 +392,12 @@ dependencies = [
|
|||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.23"
|
version = "1.2.23"
|
||||||
@ -327,6 +524,15 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fast-math"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2465292146cdfc2011350fe3b1c616ac83cf0faeedb33463ba1c332ed8948d66"
|
||||||
|
dependencies = [
|
||||||
|
"ieee754",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "feature-probe"
|
name = "feature-probe"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
@ -412,6 +618,30 @@ version = "0.15.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ieee754"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9007da9cacbd3e6343da136e98b0d2df013f553d35bdec8b518f07bea768e19c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.9.0"
|
version = "2.9.0"
|
||||||
@ -422,6 +652,12 @@ dependencies = [
|
|||||||
"hashbrown 0.15.2",
|
"hashbrown 0.15.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.77"
|
version = "0.3.77"
|
||||||
@ -530,6 +766,20 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
|
||||||
|
dependencies = [
|
||||||
|
"num-bigint",
|
||||||
|
"num-complex",
|
||||||
|
"num-integer",
|
||||||
|
"num-iter",
|
||||||
|
"num-rational",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint"
|
name = "num-bigint"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@ -540,6 +790,15 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-complex"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-derive"
|
name = "num-derive"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
@ -560,6 +819,28 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-iter"
|
||||||
|
version = "0.1.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-rational"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
|
||||||
|
dependencies = [
|
||||||
|
"num-bigint",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.19"
|
version = "0.2.19"
|
||||||
@ -640,6 +921,40 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyth-solana-receiver-sdk"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f07e92abfc18154532ed3dabaa7dac8e693b9925bfe28b2915bc8f8c1540ca0"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-lang",
|
||||||
|
"bytemuck_derive",
|
||||||
|
"hex",
|
||||||
|
"pythnet-sdk",
|
||||||
|
"solana-program",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pythnet-sdk"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "498d20fd330277697aaee92f341bdabdb4695b10e05f054157a18ad8b7746a17"
|
||||||
|
dependencies = [
|
||||||
|
"anchor-lang",
|
||||||
|
"bincode",
|
||||||
|
"borsh 0.10.4",
|
||||||
|
"bytemuck",
|
||||||
|
"byteorder",
|
||||||
|
"fast-math",
|
||||||
|
"hex",
|
||||||
|
"rustc_version",
|
||||||
|
"serde",
|
||||||
|
"sha3",
|
||||||
|
"slow_primes",
|
||||||
|
"solana-program",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.40"
|
version = "1.0.40"
|
||||||
@ -744,6 +1059,12 @@ version = "1.0.20"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
@ -785,6 +1106,18 @@ dependencies = [
|
|||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.140"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.9.9"
|
version = "0.9.9"
|
||||||
@ -830,6 +1163,8 @@ dependencies = [
|
|||||||
name = "shine_payments"
|
name = "shine_payments"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anchor-lang",
|
||||||
|
"pyth-solana-receiver-sdk",
|
||||||
"solana-program",
|
"solana-program",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -846,6 +1181,15 @@ version = "1.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slow_primes"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "58267dd2fbaa6dceecba9e3e106d2d90a2b02497c0e8b01b8759beccf5113938"
|
||||||
|
dependencies = [
|
||||||
|
"num",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.15.0"
|
version = "1.15.0"
|
||||||
@ -1035,7 +1379,7 @@ dependencies = [
|
|||||||
"solana-pubkey",
|
"solana-pubkey",
|
||||||
"solana-sdk-ids",
|
"solana-sdk-ids",
|
||||||
"solana-system-interface",
|
"solana-system-interface",
|
||||||
"thiserror",
|
"thiserror 2.0.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1318,7 +1662,7 @@ dependencies = [
|
|||||||
"solana-sysvar",
|
"solana-sysvar",
|
||||||
"solana-sysvar-id",
|
"solana-sysvar-id",
|
||||||
"solana-vote-interface",
|
"solana-vote-interface",
|
||||||
"thiserror",
|
"thiserror 2.0.12",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1449,7 +1793,7 @@ checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"libsecp256k1",
|
"libsecp256k1",
|
||||||
"solana-define-syscall",
|
"solana-define-syscall",
|
||||||
"thiserror",
|
"thiserror 2.0.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1674,13 +2018,33 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.12"
|
version = "2.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl 2.0.12",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1747,6 +2111,12 @@ version = "1.0.18"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
|
|||||||
@ -350,10 +350,18 @@ next_index = tickets_paid + 1
|
|||||||
Проверки oracle:
|
Проверки oracle:
|
||||||
|
|
||||||
- передан именно тот oracle account, что указан в settings;
|
- передан именно тот oracle account, что указан в settings;
|
||||||
- feed id совпадает с ожидаемым;
|
- owner oracle-аккаунта совпадает с Pyth Solana Receiver program;
|
||||||
|
- feed id совпадает с ожидаемым `PYTH_SOL_USD_FEED_ID`;
|
||||||
|
- verification level должен быть `Full`;
|
||||||
- цена не старше `ORACLE_MAX_AGE_SECS`;
|
- цена не старше `ORACLE_MAX_AGE_SECS`;
|
||||||
|
- доверительный интервал (`conf`) не должен быть шире `ORACLE_MAX_CONFIDENCE_PPM`;
|
||||||
- цена положительная и корректно переводима в ratio.
|
- цена положительная и корректно переводима в ratio.
|
||||||
|
|
||||||
|
Реализация чтения:
|
||||||
|
|
||||||
|
- для декодирования price update используется официальный open-source `pyth-solana-receiver-sdk`;
|
||||||
|
- ручной парсинг по фиксированным offset-ам не используется.
|
||||||
|
|
||||||
Внутренние преобразования:
|
Внутренние преобразования:
|
||||||
|
|
||||||
- `lamports -> usd_cents` делаются с округлением вниз;
|
- `lamports -> usd_cents` делаются с округлением вниз;
|
||||||
|
|||||||
@ -12,6 +12,8 @@ doctest = false
|
|||||||
bench = false
|
bench = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anchor-lang = "=0.31.1"
|
||||||
|
pyth-solana-receiver-sdk = "=0.6.0"
|
||||||
solana-program = "2.1.21"
|
solana-program = "2.1.21"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
use anchor_lang::AccountDeserialize;
|
||||||
|
use pyth_solana_receiver_sdk::error::GetPriceError;
|
||||||
|
use pyth_solana_receiver_sdk::price_update::{get_feed_id_from_hex, FeedId, PriceUpdateV2};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::{next_account_info, AccountInfo},
|
account_info::{next_account_info, AccountInfo},
|
||||||
clock::Clock,
|
clock::Clock,
|
||||||
@ -1062,21 +1065,50 @@ fn read_sol_usd_price(price_update: &AccountInfo, key: &Pubkey) -> Result<SolUsd
|
|||||||
let expected_oracle = Pubkey::from_str(settings::PYTH_SOL_USD_ACCOUNT)
|
let expected_oracle = Pubkey::from_str(settings::PYTH_SOL_USD_ACCOUNT)
|
||||||
.map_err(|_| ProgramError::from(PaymentsError::InvalidOracleFeedConfig))?;
|
.map_err(|_| ProgramError::from(PaymentsError::InvalidOracleFeedConfig))?;
|
||||||
require_keys_eq!(expected_oracle, *key, PaymentsError::InvalidOracleAccount);
|
require_keys_eq!(expected_oracle, *key, PaymentsError::InvalidOracleAccount);
|
||||||
|
require_keys_eq!(*price_update.owner, pyth_solana_receiver_sdk::ID, PaymentsError::InvalidOracleAccount);
|
||||||
|
|
||||||
let data = price_update.try_borrow_data()?;
|
let data = price_update.try_borrow_data()?;
|
||||||
let clock = Clock::get()?;
|
let clock = Clock::get()?;
|
||||||
parse_pyth_price_update_v2(&data, &clock)
|
let mut data_slice: &[u8] = &data;
|
||||||
|
let price_update_state = PriceUpdateV2::try_deserialize(&mut data_slice)
|
||||||
|
.map_err(|_| ProgramError::from(PaymentsError::InvalidOraclePrice))?;
|
||||||
|
let feed_id = expected_sol_usd_feed_id()?;
|
||||||
|
let price = price_update_state
|
||||||
|
.get_price_no_older_than(&clock, settings::ORACLE_MAX_AGE_SECS, &feed_id)
|
||||||
|
.map_err(map_pyth_price_error)?;
|
||||||
|
require!(price.price > 0, PaymentsError::InvalidOraclePrice);
|
||||||
|
require_oracle_confidence_ok(price.price, price.conf)?;
|
||||||
|
sol_usd_price_from_components(price.price, price.exponent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pyth_price_update_v2(data: &[u8], clock: &Clock) -> Result<SolUsdPrice, ProgramError> {
|
fn expected_sol_usd_feed_id() -> Result<FeedId, ProgramError> {
|
||||||
require!(data.len() > 100, PaymentsError::InvalidOraclePrice);
|
get_feed_id_from_hex(settings::PYTH_SOL_USD_FEED_ID)
|
||||||
let price = read_i64_at(data, 73)?;
|
.map_err(|_| ProgramError::from(PaymentsError::InvalidOracleFeedConfig))
|
||||||
let exponent = read_i32_at(data, 89)?;
|
}
|
||||||
let publish_time = read_i64_at(data, 93)?;
|
|
||||||
|
fn map_pyth_price_error(err: GetPriceError) -> ProgramError {
|
||||||
|
match err {
|
||||||
|
GetPriceError::PriceTooOld => PaymentsError::OraclePriceTooOld.into(),
|
||||||
|
GetPriceError::MismatchedFeedId => PaymentsError::InvalidOracleFeed.into(),
|
||||||
|
GetPriceError::InsufficientVerificationLevel => PaymentsError::InvalidOraclePrice.into(),
|
||||||
|
GetPriceError::FeedIdMustBe32Bytes | GetPriceError::FeedIdNonHexCharacter => {
|
||||||
|
PaymentsError::InvalidOracleFeedConfig.into()
|
||||||
|
}
|
||||||
|
GetPriceError::InvalidWindowSize => PaymentsError::InvalidOraclePrice.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn require_oracle_confidence_ok(price: i64, conf: u64) -> ProgramResult {
|
||||||
|
require!(price > 0, PaymentsError::InvalidOraclePrice);
|
||||||
|
let conf_ppm = checked_mul_u128(conf as u128, 1_000_000u128)? / (price as u128);
|
||||||
require!(
|
require!(
|
||||||
publish_time.saturating_add(settings::ORACLE_MAX_AGE_SECS as i64) >= clock.unix_timestamp,
|
conf_ppm <= settings::ORACLE_MAX_CONFIDENCE_PPM as u128,
|
||||||
PaymentsError::OraclePriceTooOld
|
PaymentsError::InvalidOraclePrice
|
||||||
);
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sol_usd_price_from_components(price: i64, exponent: i32) -> Result<SolUsdPrice, ProgramError> {
|
||||||
require!(price > 0, PaymentsError::InvalidOraclePrice);
|
require!(price > 0, PaymentsError::InvalidOraclePrice);
|
||||||
let mut num = checked_mul_u128(price as u128, settings::USD_CENTS_SCALE as u128)?;
|
let mut num = checked_mul_u128(price as u128, settings::USD_CENTS_SCALE as u128)?;
|
||||||
let mut den: u128 = 1;
|
let mut den: u128 = 1;
|
||||||
@ -1097,34 +1129,6 @@ fn parse_pyth_price_update_v2(data: &[u8], clock: &Clock) -> Result<SolUsdPrice,
|
|||||||
Ok(SolUsdPrice { price_num: num, price_den: den })
|
Ok(SolUsdPrice { price_num: num, price_den: den })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_i32_at(data: &[u8], offset: usize) -> Result<i32, ProgramError> {
|
|
||||||
let end = offset
|
|
||||||
.checked_add(4)
|
|
||||||
.ok_or(ProgramError::from(PaymentsError::InvalidOraclePrice))?;
|
|
||||||
let slice = data
|
|
||||||
.get(offset..end)
|
|
||||||
.ok_or(ProgramError::from(PaymentsError::InvalidOraclePrice))?;
|
|
||||||
Ok(i32::from_le_bytes(
|
|
||||||
slice
|
|
||||||
.try_into()
|
|
||||||
.map_err(|_| ProgramError::from(PaymentsError::InvalidOraclePrice))?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_i64_at(data: &[u8], offset: usize) -> Result<i64, ProgramError> {
|
|
||||||
let end = offset
|
|
||||||
.checked_add(8)
|
|
||||||
.ok_or(ProgramError::from(PaymentsError::InvalidOraclePrice))?;
|
|
||||||
let slice = data
|
|
||||||
.get(offset..end)
|
|
||||||
.ok_or(ProgramError::from(PaymentsError::InvalidOraclePrice))?;
|
|
||||||
Ok(i64::from_le_bytes(
|
|
||||||
slice
|
|
||||||
.try_into()
|
|
||||||
.map_err(|_| ProgramError::from(PaymentsError::InvalidOraclePrice))?,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lamports_to_usd_cents_floor(lamports: u64, price: &SolUsdPrice) -> Result<u64, ProgramError> {
|
fn lamports_to_usd_cents_floor(lamports: u64, price: &SolUsdPrice) -> Result<u64, ProgramError> {
|
||||||
let numerator = checked_mul_u128(lamports as u128, price.price_num)?;
|
let numerator = checked_mul_u128(lamports as u128, price.price_num)?;
|
||||||
let denominator = checked_mul_u128(settings::LAMPORTS_PER_SOL as u128, price.price_den)?;
|
let denominator = checked_mul_u128(settings::LAMPORTS_PER_SOL as u128, price.price_den)?;
|
||||||
|
|||||||
@ -45,6 +45,9 @@ pub const LAMPORTS_PER_SOL: u64 = 1_000_000_000;
|
|||||||
|
|
||||||
/// `ORACLE_MAX_AGE_SECS` — максимальный возраст oracle-цены (в секундах), допустимый для расчетов.
|
/// `ORACLE_MAX_AGE_SECS` — максимальный возраст oracle-цены (в секундах), допустимый для расчетов.
|
||||||
pub const ORACLE_MAX_AGE_SECS: u64 = 120;
|
pub const ORACLE_MAX_AGE_SECS: u64 = 120;
|
||||||
|
/// `ORACLE_MAX_CONFIDENCE_PPM` — максимальная относительная ширина доверительного интервала oracle-цены.
|
||||||
|
/// Если `conf / price` выше этого порога, цена считается слишком неопределённой для покупки и payout.
|
||||||
|
pub const ORACLE_MAX_CONFIDENCE_PPM: u64 = 100_000; // 10%
|
||||||
/// `PYTH_SOL_USD_FEED_ID` — feed id Pyth для пары SOL/USD.
|
/// `PYTH_SOL_USD_FEED_ID` — feed id Pyth для пары SOL/USD.
|
||||||
pub const PYTH_SOL_USD_FEED_ID: &str =
|
pub const PYTH_SOL_USD_FEED_ID: &str =
|
||||||
"0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d";
|
"0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d";
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user