diff --git a/Cargo.lock b/Cargo.lock index 3d96443..559f91f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,30 +29,30 @@ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aead" -version = "0.4.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ + "crypto-common", "generic-array", ] [[package]] name = "aes" -version = "0.7.5" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", "cpufeatures", - "opaque-debug", ] [[package]] name = "aes-gcm-siv" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" dependencies = [ "aead", "aes", @@ -64,14 +64,13 @@ dependencies = [ ] [[package]] -name = "ahash" -version = "0.7.8" +name = "agave-transaction-view" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +checksum = "a249374d6349eeb31348a849666f3d47cacb18e0e05454fbd11a1fc69fae8e7e" dependencies = [ - "getrandom 0.2.15", - "once_cell", - "version_check", + "solana-sdk", + "solana-svm-transaction", ] [[package]] @@ -96,12 +95,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "aliasable" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" - [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -132,20 +125,11 @@ dependencies = [ "libc", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "aquamarine" @@ -154,7 +138,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1da02abba9f9063d786eab1509833ebb2fac0f966862ca59439c76b9c566760" dependencies = [ "include_dir", - "itertools", + "itertools 0.10.5", "proc-macro-error", "proc-macro2", "quote", @@ -184,7 +168,7 @@ dependencies = [ "ark-std", "derivative", "hashbrown 0.13.2", - "itertools", + "itertools 0.10.5", "num-traits", "zeroize", ] @@ -201,7 +185,7 @@ dependencies = [ "ark-std", "derivative", "digest 0.10.7", - "itertools", + "itertools 0.10.5", "num-bigint 0.4.6", "num-traits", "paste", @@ -308,7 +292,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -348,7 +332,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", - "event-listener", + "event-listener 2.5.3", "futures-core", ] @@ -367,12 +351,14 @@ dependencies = [ ] [[package]] -name = "async-mutex" -version = "1.4.0" +name = "async-lock" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener", + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", ] [[package]] @@ -383,7 +369,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -437,10 +423,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "base64ct" -version = "1.6.0" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bincode" @@ -477,9 +463,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.1" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" dependencies = [ "arrayref", "arrayvec", @@ -495,7 +481,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array", ] @@ -508,22 +493,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "borsh" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" -dependencies = [ - "borsh-derive 0.9.3", - "hashbrown 0.11.2", -] - [[package]] name = "borsh" version = "0.10.4" @@ -544,27 +513,14 @@ dependencies = [ "cfg_aliases", ] -[[package]] -name = "borsh-derive" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" -dependencies = [ - "borsh-derive-internal 0.9.3", - "borsh-schema-derive-internal 0.9.3", - "proc-macro-crate 0.1.5", - "proc-macro2", - "syn 1.0.109", -] - [[package]] name = "borsh-derive" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" dependencies = [ - "borsh-derive-internal 0.10.4", - "borsh-schema-derive-internal 0.10.4", + "borsh-derive-internal", + "borsh-schema-derive-internal", "proc-macro-crate 0.1.5", "proc-macro2", "syn 1.0.109", @@ -580,21 +536,10 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "syn_derive", ] -[[package]] -name = "borsh-derive-internal" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "borsh-derive-internal" version = "0.10.4" @@ -606,17 +551,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "borsh-schema-derive-internal" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "borsh-schema-derive-internal" version = "0.10.4" @@ -651,9 +585,12 @@ dependencies = [ [[package]] name = "bs58" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] [[package]] name = "bumpalo" @@ -673,22 +610,22 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.7.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -699,9 +636,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "bzip2" @@ -731,7 +668,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "190baaad529bcfbde9e1a19022c42781bdb6ff9de25721abdb8fd98c0807730b" dependencies = [ "libc", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -745,6 +682,12 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "1.0.0" @@ -757,6 +700,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "cfg_eval" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "chrono" version = "0.4.38" @@ -783,51 +737,12 @@ dependencies = [ [[package]] name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", -] - -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "ansi_term", - "atty", - "bitflags 1.3.2", - "strsim 0.8.0", - "textwrap 0.11.0", - "unicode-width", - "vec_map", -] - -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_lex", - "indexmap 1.9.3", - "once_cell", - "strsim 0.10.0", - "termcolor", - "textwrap 0.16.1", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "os_str_bytes", + "crypto-common", + "inout", ] [[package]] @@ -843,6 +758,16 @@ dependencies = [ "unreachable", ] +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -885,12 +810,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "const-oid" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" - [[package]] name = "constant_time_eq" version = "0.3.1" @@ -978,6 +897,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] @@ -993,27 +913,55 @@ dependencies = [ [[package]] name = "ctr" -version = "0.8.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ "cipher", ] [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", "serde", "subtle", "zeroize", ] +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "darling" version = "0.20.10" @@ -1034,8 +982,8 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim 0.11.1", - "syn 2.0.77", + "strsim", + "syn 2.0.90", ] [[package]] @@ -1046,7 +994,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1069,15 +1017,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" -[[package]] -name = "der" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" -dependencies = [ - "const-oid", -] - [[package]] name = "der-parser" version = "8.2.0" @@ -1118,18 +1057,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "dialoguer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" -dependencies = [ - "console", - "shell-words", - "tempfile", - "zeroize", -] - [[package]] name = "difflib" version = "0.4.0" @@ -1173,7 +1100,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1196,7 +1123,7 @@ checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1226,7 +1153,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 3.2.0", "ed25519", "rand 0.7.3", "serde", @@ -1296,7 +1223,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1309,7 +1236,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -1333,12 +1260,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1347,6 +1274,27 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +dependencies = [ + "event-listener 5.3.1", + "pin-project-lite", +] + [[package]] name = "fastrand" version = "2.1.1" @@ -1359,6 +1307,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "filetime" version = "0.2.25" @@ -1428,9 +1382,9 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -1443,9 +1397,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1453,15 +1407,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -1470,38 +1424,44 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1569,14 +1529,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] -name = "goblin" -version = "0.5.4" +name = "governor" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" dependencies = [ - "log", - "plain", - "scroll", + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.8.5", + "smallvec", + "spinning_top", ] [[package]] @@ -1591,7 +1560,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.5.0", + "indexmap", "slab", "tokio", "tokio-util 0.7.12", @@ -1607,31 +1576,13 @@ dependencies = [ "byteorder", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash 0.7.8", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.8", -] - [[package]] name = "hashbrown" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.11", + "ahash", ] [[package]] @@ -1640,6 +1591,12 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + [[package]] name = "heck" version = "0.4.1" @@ -1770,7 +1727,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls", + "rustls 0.21.12", "tokio", "tokio-rustls", ] @@ -1857,22 +1814,12 @@ checksum = "4e6ba961c14e98151cd6416dd3685efe786a94c38bc1a535c06ceff0a1600813" [[package]] name = "indexmap" -version = "1.9.3" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.2", ] [[package]] @@ -1888,6 +1835,15 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "instant" version = "0.1.13" @@ -1912,6 +1868,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -1919,20 +1884,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] -name = "jobserver" -version = "0.1.32" +name = "jni" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" dependencies = [ - "libc", + "cesu8", + "combine 4.6.7", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", ] [[package]] -name = "js-sys" -version = "0.3.70" +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -1968,9 +1954,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libredox" @@ -2040,7 +2026,7 @@ dependencies = [ "ark-bn254", "ark-ff", "num-bigint 0.4.6", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2065,29 +2051,20 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "lru" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" -dependencies = [ - "hashbrown 0.12.3", -] - [[package]] name = "lz4" -version = "1.27.0" +version = "1.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a231296ca742e418c43660cb68e082486ff2538e8db432bc818580f3965025ed" +checksum = "4d1febb2b4a79ddd1980eede06a8f7902197960aa0383ffcfdd62fe723036725" dependencies = [ "lz4-sys", ] [[package]] name = "lz4-sys" -version = "1.11.0" +version = "1.11.1+lz4-1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb44a01837a858d47e5a630d2ccf304c8efcc4b83b8f9f75b7a9ee4fcc6e57d" +checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6" dependencies = [ "cc", "libc", @@ -2108,15 +2085,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.9.1" @@ -2144,6 +2112,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2219,19 +2197,60 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "mollusk-svm" +version = "0.0.13" +source = "git+https://github.com/buffalojoec/mollusk.git#c01523016195c315870bd9e4bfa3a64a6cffa659" +dependencies = [ + "bincode", + "mollusk-svm-error", + "mollusk-svm-keys", + "solana-bpf-loader-program", + "solana-compute-budget", + "solana-logger", + "solana-program-runtime", + "solana-sdk", + "solana-system-program", + "solana-timings", +] + +[[package]] +name = "mollusk-svm-error" +version = "0.0.13" +source = "git+https://github.com/buffalojoec/mollusk.git#c01523016195c315870bd9e4bfa3a64a6cffa659" +dependencies = [ + "solana-sdk", + "thiserror 1.0.69", +] + +[[package]] +name = "mollusk-svm-keys" +version = "0.0.13" +source = "git+https://github.com/buffalojoec/mollusk.git#c01523016195c315870bd9e4bfa3a64a6cffa659" +dependencies = [ + "mollusk-svm-error", + "solana-sdk", +] + [[package]] name = "nix" -version = "0.26.4" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "cfg-if", + "cfg_aliases", "libc", - "memoffset 0.7.1", - "pin-utils", + "memoffset", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + [[package]] name = "nom" version = "7.1.3" @@ -2242,6 +2261,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "normalize-line-endings" version = "0.3.0" @@ -2299,17 +2324,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "num-derive" version = "0.4.2" @@ -2318,7 +2332,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -2372,34 +2386,13 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive 0.6.1", -] - [[package]] name = "num_enum" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ - "num_enum_derive 0.7.3", -] - -[[package]] -name = "num_enum_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 2.0.77", + "num_enum_derive", ] [[package]] @@ -2411,7 +2404,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -2472,37 +2465,14 @@ dependencies = [ "percent-encoding", "pin-project", "rand 0.8.5", - "thiserror", -] - -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - -[[package]] -name = "ouroboros" -version = "0.15.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db" -dependencies = [ - "aliasable", - "ouroboros_macro", + "thiserror 1.0.69", ] [[package]] -name = "ouroboros_macro" -version = "0.15.6" +name = "parking" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" -dependencies = [ - "Inflector", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -2533,15 +2503,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pbkdf2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" -dependencies = [ - "crypto-mac", -] - [[package]] name = "pbkdf2" version = "0.11.0" @@ -2592,7 +2553,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -2638,34 +2599,17 @@ dependencies = [ "pinocchio", ] -[[package]] -name = "pkcs8" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" -dependencies = [ - "der", - "spki", - "zeroize", -] - [[package]] name = "pkg-config" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - [[package]] name = "polyval" -version = "0.5.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", @@ -2702,7 +2646,7 @@ checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "float-cmp", - "itertools", + "itertools 0.10.5", "normalize-line-endings", "predicates-core", "regex", @@ -2733,23 +2677,13 @@ dependencies = [ "toml", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.22.22", + "toml_edit", ] [[package]] @@ -2778,9 +2712,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -2802,55 +2736,75 @@ checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", +] + +[[package]] +name = "quanta" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773ce68d0bb9bc7ef20be3536ffe94e223e1f365bd374108b2659fac0c65cfe6" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", ] [[package]] name = "quinn" -version = "0.10.2" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" dependencies = [ "bytes", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls", - "thiserror", + "rustls 0.23.20", + "socket2", + "thiserror 2.0.9", "tokio", "tracing", ] [[package]] name = "quinn-proto" -version = "0.10.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ "bytes", + "getrandom 0.2.15", "rand 0.8.5", - "ring 0.16.20", + "ring", "rustc-hash", - "rustls", - "rustls-native-certs", + "rustls 0.23.20", + "rustls-pki-types", + "rustls-platform-verifier", "slab", - "thiserror", + "thiserror 2.0.9", "tinyvec", "tracing", + "web-time", ] [[package]] name = "quinn-udp" -version = "0.4.1" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904" dependencies = [ - "bytes", + "cfg_aliases", "libc", + "once_cell", "socket2", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -2942,6 +2896,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "raw-cpuid" +version = "11.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "rayon" version = "1.10.0" @@ -2962,18 +2925,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "rcgen" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" -dependencies = [ - "pem", - "ring 0.16.20", - "time", - "yasna", -] - [[package]] name = "redox_syscall" version = "0.5.6" @@ -2985,9 +2936,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -2997,9 +2948,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -3008,9 +2959,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" @@ -3033,11 +2984,12 @@ dependencies = [ "js-sys", "log", "mime", + "mime_guess", "once_cell", "percent-encoding", "pin-project-lite", - "rustls", - "rustls-pemfile", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -3056,18 +3008,18 @@ dependencies = [ ] [[package]] -name = "ring" -version = "0.16.20" +name = "reqwest-middleware" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "5a735987236a8e238bf0296c7e351b999c188ccc11477f311b82b55c93984216" dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", + "anyhow", + "async-trait", + "http", + "reqwest", + "serde", + "task-local-extensions", + "thiserror 1.0.69", ] [[package]] @@ -3080,32 +3032,11 @@ dependencies = [ "cfg-if", "getrandom 0.2.15", "libc", - "spin 0.9.8", - "untrusted 0.9.0", + "spin", + "untrusted", "windows-sys 0.52.0", ] -[[package]] -name = "rpassword" -version = "7.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" -dependencies = [ - "libc", - "rtoolbox", - "windows-sys 0.48.0", -] - -[[package]] -name = "rtoolbox" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -3114,9 +3045,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustc_version" @@ -3138,15 +3069,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3156,19 +3087,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.17.8", - "rustls-webpki", + "ring", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.23.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 2.2.0", + "rustls-pki-types", "schannel", "security-framework", ] @@ -3182,14 +3128,70 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +dependencies = [ + "web-time", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c7dc240fec5517e6c4eab3310438636cfe6391dfc345ba013109909a90d136" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.20", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki 0.102.8", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", + "ring", + "untrusted", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] @@ -3233,29 +3235,15 @@ name = "scroll" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" -dependencies = [ - "scroll_derive", -] [[package]] -name = "scroll_derive" -version = "0.11.1" +name = "sct" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.77", -] - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] @@ -3268,6 +3256,7 @@ dependencies = [ "core-foundation", "core-foundation-sys", "libc", + "num-bigint 0.4.6", "security-framework-sys", ] @@ -3298,9 +3287,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] @@ -3316,20 +3305,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" dependencies = [ "itoa", "memchr", @@ -3351,24 +3340,25 @@ dependencies = [ [[package]] name = "serde_with" -version = "2.3.3" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" dependencies = [ "serde", + "serde_derive", "serde_with_macros", ] [[package]] name = "serde_with_macros" -version = "2.3.3" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -3406,18 +3396,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", -] - [[package]] name = "sha3" version = "0.10.8" @@ -3437,12 +3415,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shell-words" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" - [[package]] name = "shlex" version = "1.3.0" @@ -3505,14 +3477,28 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "solana-account" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "730219420b206253977b8cc8fd7846ffe021ab2e2c718e70db420efbd2775547" +dependencies = [ + "bincode", + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-program", +] + [[package]] name = "solana-account-decoder" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e54ec43b0262c19a3c87bf2dbd52c6bc6d4f9307246fe4b666fd87f06305e5" +checksum = "14e5b1c167335942b659d077552607f79b2eca3472e40eeed97a2c55838b84ef" dependencies = [ "Inflector", - "base64 0.21.7", + "base64 0.22.1", "bincode", "bs58", "bv", @@ -3520,103 +3506,125 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "solana-account-decoder-client-types", "solana-config-program", "solana-sdk", - "spl-token", + "spl-token 6.0.0", "spl-token-2022", "spl-token-group-interface", "spl-token-metadata-interface", - "thiserror", + "thiserror 1.0.69", + "zstd", +] + +[[package]] +name = "solana-account-decoder-client-types" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee0750d2f106ecbee6d4508b6e2029e6946cb5f67288bf002b5a62f9f451c43" +dependencies = [ + "base64 0.22.1", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account", + "solana-pubkey", "zstd", ] +[[package]] +name = "solana-account-info" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6abe81cfc4a75f71a510c6856b03a7d8525e416af3c69d55daef62e6078b8d40" +dependencies = [ + "bincode", + "serde", + "solana-program-error", + "solana-program-memory", + "solana-pubkey", +] + [[package]] name = "solana-accounts-db" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da22e7afc30fa3d6367f4a5230c843ec2bfd27456b9f3b7ec144c112eaca303a" +checksum = "b9fecc332ad4edd98ed63e5a46d990ecaf6fe4abd2bf9795c15474a64534ced6" dependencies = [ - "arrayref", + "ahash", "bincode", "blake3", "bv", "bytemuck", - "byteorder", + "bytemuck_derive", "bzip2", "crossbeam-channel", "dashmap", - "flate2", - "fnv", - "im", "index_list", - "itertools", + "indexmap", + "itertools 0.12.1", "lazy_static", "log", "lz4", "memmap2", "modular-bitfield", - "num-derive 0.4.2", - "num-traits", "num_cpus", - "num_enum 0.7.3", - "ouroboros", - "percentage", - "qualifier_attr", + "num_enum", "rand 0.8.5", "rayon", - "regex", - "rustc_version", "seqlock", "serde", "serde_derive", "smallvec", "solana-bucket-map", - "solana-config-program", - "solana-frozen-abi", - "solana-frozen-abi-macro", + "solana-inline-spl", + "solana-lattice-hash", "solana-measure", "solana-metrics", "solana-nohash-hasher", - "solana-program-runtime", "solana-rayon-threadlimit", "solana-sdk", - "solana-stake-program", - "solana-system-program", - "solana-vote-program", + "solana-svm-transaction", "static_assertions", - "strum", - "strum_macros", "tar", "tempfile", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "solana-address-lookup-table-program" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2601a7879e6db5f9af09801f2c99032a204849643832dae4a96495b86e789b0e" +checksum = "2cf79a76f2878982b9781dfd0831d58ee15eb905be65406ccf7370c3ecd69c52" dependencies = [ "bincode", "bytemuck", "log", - "num-derive 0.4.2", + "num-derive", "num-traits", - "rustc_version", - "serde", - "solana-frozen-abi", - "solana-frozen-abi-macro", + "solana-feature-set", + "solana-log-collector", "solana-program", "solana-program-runtime", "solana-sdk", - "thiserror", + "thiserror 1.0.69", +] + +[[package]] +name = "solana-atomic-u64" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391b795afcdcad39ddc6c938d64b789d036cdfe00d9dc5ff83024cf2da9f066f" +dependencies = [ + "parking_lot", ] [[package]] name = "solana-banks-client" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48b38e77fde55eaa036666461c61df36238416908c5a4737b59cd1b6165736dc" +checksum = "2f857fb6590467d433f40eee507666ca496ec67907e50b7d530b6c04f6541875" dependencies = [ "borsh 1.5.1", "futures", @@ -3624,73 +3632,120 @@ dependencies = [ "solana-program", "solana-sdk", "tarpc", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-serde", ] [[package]] name = "solana-banks-interface" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cb66654fa16a519efe8bb54eacfd0e9a3862f916d925cd24b63041b113c8a1" +checksum = "20052d231bb9ac3268dc61a713e3915d6c95fc942f9a5c15ca3a81a3fcd9cc12" dependencies = [ "serde", + "serde_derive", "solana-sdk", "tarpc", ] [[package]] name = "solana-banks-server" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "964127e858fb510ff017981acab11ac376ecfee3b10c03c379ff084a52e14969" +checksum = "10db60e4bf077b870a7e75f8596bf3790d079b3762e9b4edc032475077007d0b" dependencies = [ "bincode", "crossbeam-channel", "futures", - "solana-accounts-db", "solana-banks-interface", "solana-client", + "solana-feature-set", "solana-runtime", "solana-sdk", "solana-send-transaction-service", + "solana-svm", "tarpc", "tokio", "tokio-serde", ] +[[package]] +name = "solana-bincode" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e85cb5961c356345a61378163fd9057011b35540f8bcdd8d8a09cb10117264f" +dependencies = [ + "bincode", + "serde", + "solana-instruction", +] + +[[package]] +name = "solana-bn254" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39c4030db26ad618f7e18fb5284df19fd52a68e092a1ca58db857108c4cc777" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "bytemuck", + "solana-program", + "thiserror 1.0.69", +] + +[[package]] +name = "solana-borsh" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d526f3525ab22a3ada3f9a1d642664dafac00dc9208326b701a2045514eb04" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.1", +] + [[package]] name = "solana-bpf-loader-program" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da1c1bf12ec90f8a67706e6e5ffc91e2198b85a07bd12c56c44967d13bba7e7f" +checksum = "142e0407f8428a1d2a33154d1d3d1c134ad257651ddff0811c17a6ee840def36" dependencies = [ "bincode", "byteorder", "libsecp256k1", "log", "scopeguard", + "solana-bn254", + "solana-compute-budget", + "solana-curve25519", + "solana-feature-set", + "solana-log-collector", "solana-measure", + "solana-poseidon", + "solana-program-memory", "solana-program-runtime", "solana-sdk", - "solana-zk-token-sdk", + "solana-timings", + "solana-type-overrides", "solana_rbpf", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "solana-bucket-map" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ed4b533159ec832f534a5b4efb10946d392b15efc88ca2107bdbb39b5d0646" +checksum = "66eb348939fcfea6e40eed61bca06a1c631f8cb70f1801a5b14021bddefe93eb" dependencies = [ "bv", "bytemuck", + "bytemuck_derive", "log", "memmap2", "modular-bitfield", - "num_enum 0.7.3", + "num_enum", "rand 0.8.5", "solana-measure", "solana-sdk", @@ -3698,41 +3753,43 @@ dependencies = [ ] [[package]] -name = "solana-clap-utils" -version = "1.18.23" +name = "solana-builtins-default-costs" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117bf11e4d15b529dd9dfa2680abaf8bd3c1d8f7cb0586a5accdac5a2ecc7cc5" +checksum = "854270e266040355f5fd5b67c91855bc36cebf1d3f325eb54d8b1b0ca385f74b" dependencies = [ - "chrono", - "clap 2.34.0", - "rpassword", - "solana-remote-wallet", + "ahash", + "lazy_static", + "log", + "solana-address-lookup-table-program", + "solana-bpf-loader-program", + "solana-compute-budget-program", + "solana-config-program", + "solana-loader-v4-program", "solana-sdk", - "thiserror", - "tiny-bip39", - "uriparse", - "url", + "solana-stake-program", + "solana-system-program", + "solana-vote-program", ] [[package]] name = "solana-client" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1501330d85c1a790f45f11330616bd6f0b9acd2193477268a65a38ce3b7cfdd0" +checksum = "1d9a40b8e9e11604e8c05e8b5fcdb89359235db47d1aae84dcba0fc98e95dd0c" dependencies = [ "async-trait", "bincode", "dashmap", "futures", "futures-util", - "indexmap 2.5.0", + "indexmap", "indicatif", "log", "quinn", "rayon", "solana-connection-cache", "solana-measure", - "solana-metrics", "solana-pubsub-client", "solana-quic-client", "solana-rpc-client", @@ -3743,15 +3800,35 @@ dependencies = [ "solana-thin-client", "solana-tpu-client", "solana-udp-client", - "thiserror", + "thiserror 1.0.69", "tokio", ] +[[package]] +name = "solana-clock" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7848171e53fa528efd41dd4b3ab919f47b851f8bb4a827d63ff95678f08737fc" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-macro", +] + +[[package]] +name = "solana-compute-budget" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebf2f023f471bd1195b7f420e13ffc2422592dd48e71104b4901300b49ac493e" +dependencies = [ + "solana-sdk", +] + [[package]] name = "solana-compute-budget-program" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a43d1ca229c5f761b9be38bd7dbc7c034cfb214dcbfef9691314ae4c778451c" +checksum = "73eddf023f02a56daa838818e30894b874368a741782457468eeefdfce2f7f53" dependencies = [ "solana-program-runtime", "solana-sdk", @@ -3759,190 +3836,362 @@ dependencies = [ [[package]] name = "solana-config-program" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00d0d031f3d97e3f59305c4aabf9da7359fad86dbaeb43b61a1ea13224e0b8a" +checksum = "a035a01970ebbf40a244b3b79af533329ac8d48d80b0b98e166e23e35aa88171" dependencies = [ "bincode", "chrono", "serde", "serde_derive", + "solana-log-collector", "solana-program-runtime", "solana-sdk", + "solana-short-vec", ] [[package]] name = "solana-connection-cache" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fa9ff6c33772441670e446b1d43e787aa315e95f2f9c14e3e9508b814bc8e5" +checksum = "5f45dd2a6d5d55ed951781486231d0d2ee9ff7047fdafaed01ee021e236319d0" dependencies = [ "async-trait", "bincode", "crossbeam-channel", "futures-util", - "indexmap 2.5.0", + "indexmap", "log", "rand 0.8.5", "rayon", - "rcgen", "solana-measure", "solana-metrics", "solana-sdk", - "thiserror", + "thiserror 1.0.69", "tokio", ] [[package]] name = "solana-cost-model" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "992d3d9e5cd8df6a393d66c2d52ba18afd3988f142a44f1ff26541fb3c0dd5b7" +checksum = "448128561bb950bce19cdbbdc1780955a52ef25f1984c9c13b35b4b9cdc548c4" dependencies = [ + "ahash", "lazy_static", "log", - "rustc_version", - "solana-address-lookup-table-program", - "solana-bpf-loader-program", - "solana-compute-budget-program", - "solana-config-program", - "solana-frozen-abi", - "solana-frozen-abi-macro", - "solana-loader-v4-program", + "solana-builtins-default-costs", + "solana-compute-budget", + "solana-feature-set", "solana-metrics", - "solana-program-runtime", + "solana-runtime-transaction", "solana-sdk", - "solana-stake-program", - "solana-system-program", + "solana-svm-transaction", "solana-vote-program", ] [[package]] -name = "solana-frozen-abi" -version = "1.18.23" +name = "solana-cpi" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bfcde2fc6946c99c7e3400fadd04d1628d675bfd66cb34d461c0f3224bd27d1" +checksum = "25c536ad0ce25d84a64f48dedcb773e764827e0ef781eda41fa1fa35f5d64b38" dependencies = [ - "block-buffer 0.10.4", - "bs58", - "bv", - "either", - "generic-array", - "im", - "lazy_static", - "log", - "memmap2", - "rustc_version", - "serde", - "serde_bytes", - "serde_derive", - "sha2 0.10.8", - "solana-frozen-abi-macro", - "subtle", - "thiserror", + "solana-account-info", + "solana-define-syscall", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-stable-layout", ] [[package]] -name = "solana-frozen-abi-macro" -version = "1.18.23" +name = "solana-curve25519" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5024d241425f4e99f112ee03bfa89e526c86c7ca9bd7e13448a7f2dffb7e060" +checksum = "f934d38b6f2a940fb1e1d8eaa17a14ffd3773b37be9fb29fa4bcec1bac5e4591" dependencies = [ - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.77", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-program", + "thiserror 1.0.69", ] [[package]] -name = "solana-loader-v4-program" -version = "1.18.23" +name = "solana-decode-error" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5607358636671522978533b77ff409b634b2ea53d94fd32dec4b4bcf7fe5c7e" +checksum = "c5a431f532d030098e81d120877f2dddbd3dd90bea5b259198a6aae4ff6456c3" dependencies = [ - "log", - "solana-measure", - "solana-program-runtime", - "solana-sdk", - "solana_rbpf", + "num-traits", ] [[package]] -name = "solana-logger" -version = "1.18.23" +name = "solana-define-syscall" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7062ae1de58e294d3bee5fd2c89efc155b7f7383ddce4cb88345dfafaaabc5bd" + +[[package]] +name = "solana-derivation-path" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10948c30d138d6fbfc2ae78a4882be5a9ebffa4bb1239c4efc386104ebc35b7f" +checksum = "12080d9bf8eecd559c6f40b5aaf9e47f7f28f515218087f83f02e493b46d8388" dependencies = [ - "env_logger", - "lazy_static", - "log", + "derivation-path", + "qstring", + "uriparse", ] [[package]] -name = "solana-measure" -version = "1.18.23" +name = "solana-epoch-schedule" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379355a731abf50bb5ef1e4afba02ac8c835c25bb18e32229bb481657d5c9eca" +checksum = "65c4cf7d7c266d353169cf4feeada5e4bba3a55f33715535fa1ef49080eac3e0" dependencies = [ - "log", - "solana-sdk", + "serde", + "serde_derive", + "solana-sdk-macro", ] [[package]] -name = "solana-metrics" -version = "1.18.23" +name = "solana-feature-set" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a6f767cf39d69104bff52602f3141d6abfbdd55b4eb310f8fbbbf862b27e6f" +checksum = "5cebf45992982065a0b01b4e109bf039b2ebf6394b21672382fd951516d4c9b0" dependencies = [ - "crossbeam-channel", - "gethostname", "lazy_static", - "log", - "reqwest", - "solana-sdk", - "thiserror", + "solana-clock", + "solana-epoch-schedule", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", ] [[package]] -name = "solana-net-utils" -version = "1.18.23" +name = "solana-fee" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c81ade42b553c7de08fb97cf3cfe44545f59a247e90042a67d224d62a8a189d7" +checksum = "833e9a34c8cb1271e360b240dce43065cc4419ad74fc7e807c4e30cf06ebca80" dependencies = [ - "bincode", - "clap 3.2.25", - "crossbeam-channel", - "log", - "nix", - "rand 0.8.5", - "serde", - "serde_derive", - "socket2", - "solana-logger", "solana-sdk", - "solana-version", - "tokio", - "url", + "solana-svm-transaction", ] [[package]] -name = "solana-nohash-hasher" -version = "0.2.1" +name = "solana-fee-calculator" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8a731ed60e89177c8a7ab05fe0f1511cedd3e70e773f288f9de33a9cfdc21e" +checksum = "c2befe056ece2eb5807298c2b569a35ee52f79df859bdd16a1f97869f8224a28" +dependencies = [ + "log", + "serde", + "serde_derive", +] [[package]] -name = "solana-perf" -version = "1.18.23" +name = "solana-hash" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecdf31e535743515d31392f210d132463300b5d3de7c3e26f6b344b6c941c42" +checksum = "1807bc4e9e1d25271514167d5a1e698ce5a330bce547a368242dd63b355b5faa" dependencies = [ - "ahash 0.8.11", - "bincode", - "bv", - "caps", - "curve25519-dalek", - "dlopen2", + "borsh 1.5.1", + "bs58", + "bytemuck", + "bytemuck_derive", + "js-sys", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-sanitize", + "wasm-bindgen", +] + +[[package]] +name = "solana-inflation" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a60b572cdf0ec8fcf5a53e5ba4e3e19814dd96c2b9c156d5828be68d0d2e7103" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-inline-spl" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24c9c6590e4eaf91efa887b2689b2941fe4b324bccd9a95f77853168f3d9a88" +dependencies = [ + "bytemuck", + "solana-pubkey", +] + +[[package]] +name = "solana-instruction" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfef689e06e5c7cb6206d4dc61ac77733de4f72d754e0d531393206abc27dbe4" +dependencies = [ + "bincode", + "borsh 1.5.1", + "getrandom 0.2.15", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-define-syscall", + "solana-pubkey", + "wasm-bindgen", +] + +[[package]] +name = "solana-last-restart-slot" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3186feae497bdfd2e77bfa56caed38b1cb1b0f389506666e3331f0b9ae799cb" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-macro", +] + +[[package]] +name = "solana-lattice-hash" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ec86f48a8694d55757922823823069a3652d2896f61f3ffc4b741646c166a62" +dependencies = [ + "base64 0.22.1", + "blake3", + "bs58", + "bytemuck", +] + +[[package]] +name = "solana-loader-v4-program" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94c6915a49e537925e934551dbce2db2357d555d257a311bbf5ba0810cb1017a" +dependencies = [ + "log", + "solana-bpf-loader-program", + "solana-compute-budget", + "solana-log-collector", + "solana-measure", + "solana-program-runtime", + "solana-sdk", + "solana-type-overrides", + "solana_rbpf", +] + +[[package]] +name = "solana-log-collector" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b529f5736a6c0794a885dac2e091138d3db6d924335906f117a62b58b0d3b5dc" +dependencies = [ + "log", +] + +[[package]] +name = "solana-logger" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "367c5431bad14b10fbb62614b48720b746672558dba3244167ff7d251890c355" +dependencies = [ + "env_logger", + "lazy_static", + "log", +] + +[[package]] +name = "solana-measure" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b2047a2f588082b71080b060918f107c3330ae1505f759c3b2d74bae9d9c88" + +[[package]] +name = "solana-metrics" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6319c74238e8ed4f7159fd37c693a574ab8316d03b053103f9cc83dce13f1d5c" +dependencies = [ + "crossbeam-channel", + "gethostname", + "lazy_static", + "log", + "reqwest", + "solana-sdk", + "thiserror 1.0.69", +] + +[[package]] +name = "solana-msg" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f7551f85064bc7299d56dbd7126258b084a2d78d0325b1579324f818b405123" +dependencies = [ + "solana-define-syscall", +] + +[[package]] +name = "solana-native-token" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0c4074f5fc67574dabd8f30fe6e51e290a812d88326b19b49c462058e23340" + +[[package]] +name = "solana-net-utils" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbac19474a4c4f91cb264c2fccead8a1a4f65384ce650b24360d9df5650e65bc" +dependencies = [ + "bincode", + "crossbeam-channel", + "log", + "nix", + "rand 0.8.5", + "serde", + "serde_derive", + "socket2", + "solana-sdk", + "tokio", + "url", +] + +[[package]] +name = "solana-nohash-hasher" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8a731ed60e89177c8a7ab05fe0f1511cedd3e70e773f288f9de33a9cfdc21e" + +[[package]] +name = "solana-packet" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dafc2d84e57dbfe32583fe915962bd2ca3af6be496628a871db3c3d697b38d7" +dependencies = [ + "bincode", + "bitflags 2.6.0", + "cfg_eval", + "serde", + "serde_derive", + "serde_with", +] + +[[package]] +name = "solana-perf" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8299f1ba518f9888da8cafa861addc6ffdd639c689e3ce219ae08212c0dcd0e" +dependencies = [ + "ahash", + "bincode", + "bv", + "caps", + "curve25519-dalek 4.1.3", + "dlopen2", "fnv", "lazy_static", "libc", @@ -3950,108 +4199,200 @@ dependencies = [ "nix", "rand 0.8.5", "rayon", - "rustc_version", "serde", - "solana-frozen-abi", - "solana-frozen-abi-macro", "solana-metrics", "solana-rayon-threadlimit", "solana-sdk", + "solana-short-vec", "solana-vote-program", ] [[package]] -name = "solana-program" -version = "1.18.23" +name = "solana-poseidon" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76056fecde0fe0ece8b457b719729c17173333471c72ad41969982975a10d6e0" +checksum = "f193a65f0db7fe5615c76c2814d6450a2e4cda61f786d5bf7a6b1ad0c179b947" dependencies = [ "ark-bn254", - "ark-ec", - "ark-ff", - "ark-serialize", - "base64 0.21.7", + "light-poseidon", + "solana-define-syscall", + "thiserror 1.0.69", +] + +[[package]] +name = "solana-precompile-error" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a30ab58b9e37cde4e5577282670f30df71b97b6b06dbdb420e9b84e57b831227" +dependencies = [ + "num-traits", + "solana-decode-error", +] + +[[package]] +name = "solana-program" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9040decf2f295d35da22557eeab3768ab8dfca8aed9afe668663c8fa0e97d60e" +dependencies = [ + "base64 0.22.1", "bincode", "bitflags 2.6.0", "blake3", "borsh 0.10.4", - "borsh 0.9.3", "borsh 1.5.1", "bs58", "bv", "bytemuck", - "cc", + "bytemuck_derive", "console_error_panic_hook", "console_log", - "curve25519-dalek", + "curve25519-dalek 4.1.3", + "five8_const", "getrandom 0.2.15", - "itertools", "js-sys", "lazy_static", - "libc", - "libsecp256k1", - "light-poseidon", "log", - "memoffset 0.9.1", + "memoffset", "num-bigint 0.4.6", - "num-derive 0.4.2", + "num-derive", "num-traits", "parking_lot", "rand 0.8.5", - "rustc_version", - "rustversion", "serde", "serde_bytes", "serde_derive", - "serde_json", "sha2 0.10.8", - "sha3 0.10.8", - "solana-frozen-abi", - "solana-frozen-abi-macro", + "sha3", + "solana-account-info", + "solana-atomic-u64", + "solana-bincode", + "solana-borsh", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-define-syscall", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-last-restart-slot", + "solana-msg", + "solana-native-token", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sanitize", "solana-sdk-macro", - "thiserror", - "tiny-bip39", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-serialize-utils", + "solana-sha256-hasher", + "solana-short-vec", + "solana-slot-hashes", + "solana-slot-history", + "solana-stable-layout", + "solana-transaction-error", + "thiserror 1.0.69", "wasm-bindgen", - "zeroize", +] + +[[package]] +name = "solana-program-entrypoint" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eb90f3fa3e979b912451a404508f1f90bb6e5c1d7767625f622b20016fb9fde" +dependencies = [ + "solana-account-info", + "solana-msg", + "solana-program-error", + "solana-pubkey", +] + +[[package]] +name = "solana-program-error" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd089caeef26dd07bd12b7b67d45e92faddc2fc67a960f316df7ae4776a2f3d5" +dependencies = [ + "borsh 1.5.1", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction", + "solana-msg", + "solana-pubkey", +] + +[[package]] +name = "solana-program-memory" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed4bc044dc2b49c323aeff04aec03c908a052e278c2edf2f7616f32fc0f1bcd9" +dependencies = [ + "num-traits", + "solana-define-syscall", +] + +[[package]] +name = "solana-program-option" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3babbdffd81994c043fc9a61458ce87496218825d6e9a303de643c0a53089b9a" + +[[package]] +name = "solana-program-pack" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fb28439d23e1f505e59c7a14ed5012365ab7aa0f20dc7bda048e02ff231cf6" +dependencies = [ + "solana-program-error", ] [[package]] name = "solana-program-runtime" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e566a9e61ecdc250824314864654dd370abf561fa8328f6e08b3bc96ccc5b80d" +checksum = "ba1de51df173401d50c0f4cf750f5070d7a4c82125a03c1aec9622dc041b0b54" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "bincode", - "eager", "enum-iterator", - "itertools", + "itertools 0.12.1", "libc", "log", - "num-derive 0.4.2", + "num-derive", "num-traits", "percentage", "rand 0.8.5", - "rustc_version", "serde", - "solana-frozen-abi", - "solana-frozen-abi-macro", + "solana-compute-budget", + "solana-feature-set", + "solana-log-collector", "solana-measure", "solana-metrics", "solana-sdk", + "solana-timings", + "solana-type-overrides", + "solana-vote", "solana_rbpf", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "solana-program-test" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b841ea7e55ee7b7e2cac034fd008c7d8cabd8b474958d4f64fcfaf76220846f5" +checksum = "974591eca853eafee8196a3445b81fd03ebd9b3e38a6dd7b6f22dc3414c32be6" dependencies = [ "assert_matches", "async-trait", - "base64 0.21.7", + "base64 0.22.1", "bincode", "chrono-humanize", "crossbeam-channel", @@ -4062,22 +4403,55 @@ dependencies = [ "solana-banks-interface", "solana-banks-server", "solana-bpf-loader-program", + "solana-compute-budget", + "solana-feature-set", + "solana-inline-spl", + "solana-instruction", + "solana-log-collector", "solana-logger", "solana-program-runtime", "solana-runtime", "solana-sdk", + "solana-svm", + "solana-timings", "solana-vote-program", "solana_rbpf", - "test-case", - "thiserror", + "thiserror 1.0.69", "tokio", ] +[[package]] +name = "solana-pubkey" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea3215775fcedf200d47590c7e2ce9a3a46bc2b7d3f77d0eae9c6edf0a39aec" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.1", + "bs58", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "five8_const", + "getrandom 0.2.15", + "js-sys", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-decode-error", + "solana-define-syscall", + "solana-sanitize", + "solana-sha256-hasher", + "wasm-bindgen", +] + [[package]] name = "solana-pubsub-client" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d997840e6d033edc4fca8f06b920726dc18d3a5bbc1e538b2154cc3b71acd1" +checksum = "9d28adf5ff89c19ef3cb24d0f484afa05852697881c2e4ef12aec190d61f76d8" dependencies = [ "crossbeam-channel", "futures-util", @@ -4090,7 +4464,7 @@ dependencies = [ "solana-account-decoder", "solana-rpc-client-api", "solana-sdk", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tokio-tungstenite", @@ -4100,20 +4474,19 @@ dependencies = [ [[package]] name = "solana-quic-client" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e689a97cefa6a005cd305210234f3dc78aacc934c0f76d210a264fae36ee432" +checksum = "259c6d420c0b7620557700f13fbbdb00afbb1b82274485c27ba30dd660ea921b" dependencies = [ - "async-mutex", + "async-lock", "async-trait", "futures", - "itertools", + "itertools 0.12.1", "lazy_static", "log", "quinn", "quinn-proto", - "rcgen", - "rustls", + "rustls 0.23.20", "solana-connection-cache", "solana-measure", "solana-metrics", @@ -4121,60 +4494,53 @@ dependencies = [ "solana-rpc-client-api", "solana-sdk", "solana-streamer", - "thiserror", + "thiserror 1.0.69", "tokio", ] [[package]] name = "solana-rayon-threadlimit" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf70f0441603e553fc3db30c1eec9f10cecc27849e7dc74d5f692d5a41a56ca" +checksum = "4c69806ad1a7b0986f750134e13e55d83919631d81a2328a588615740e14ed0a" dependencies = [ "lazy_static", "num_cpus", ] [[package]] -name = "solana-remote-wallet" -version = "1.18.23" +name = "solana-rent" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9651b3f2c3df39a1a6fc87fe792bdb3ec3d84a8169c0a57c86335b48d6cb1491" +checksum = "aab3f4a270196c38d62c3bb3c7a2f07732af2c772b50da49c9b1e2c9d2ace286" dependencies = [ - "console", - "dialoguer", - "log", - "num-derive 0.4.2", - "num-traits", - "parking_lot", - "qstring", - "semver", - "solana-sdk", - "thiserror", - "uriparse", + "serde", + "serde_derive", + "solana-sdk-macro", ] [[package]] name = "solana-rpc-client" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d753d116aacc43ef64a2bc8d25f8b20af47c366b29aa859186124e226d6e3819" +checksum = "3b05822aceeb484074a72d82a1b289da9fc3383f9ba3f55ce4bfd003bf9d62e6" dependencies = [ "async-trait", - "base64 0.21.7", + "base64 0.22.1", "bincode", "bs58", "indicatif", "log", "reqwest", + "reqwest-middleware", "semver", "serde", "serde_derive", "serde_json", - "solana-account-decoder", + "solana-account-decoder-client-types", "solana-rpc-client-api", "solana-sdk", - "solana-transaction-status", + "solana-transaction-status-client-types", "solana-version", "solana-vote-program", "tokio", @@ -4182,48 +4548,49 @@ dependencies = [ [[package]] name = "solana-rpc-client-api" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617df2c53f948c821cefca6824e376aac04ff0d844bb27f4d3ada9e211bcffe7" +checksum = "cb9c6e64f01cfafef9b2d43d6adb02979bb22f579ec8ee88b77796259acce92e" dependencies = [ - "base64 0.21.7", + "anyhow", + "base64 0.22.1", "bs58", "jsonrpc-core", "reqwest", + "reqwest-middleware", "semver", "serde", "serde_derive", "serde_json", - "solana-account-decoder", + "solana-account-decoder-client-types", + "solana-inline-spl", "solana-sdk", - "solana-transaction-status", + "solana-transaction-status-client-types", "solana-version", - "spl-token-2022", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "solana-rpc-client-nonce-utils" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d34cf36289cc35a0b18cd518a256312090368a37f40b448520e260923558a9" +checksum = "7f0ab2d1ca3769c5058c689b438d35eb1cb7d2a32fc4b2b7c16fe72fa187927c" dependencies = [ - "clap 2.34.0", - "solana-clap-utils", "solana-rpc-client", "solana-sdk", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "solana-runtime" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18dca69c7d3127d7b35014e703675a5665ed5680f6e1892acd24d612da059be9" +checksum = "60f579df1ed24b2e7be5c99c2b97cb2a331823008129103b5b7753057ddf3cf7" dependencies = [ + "ahash", "aquamarine", "arrayref", - "base64 0.21.7", + "base64 0.22.1", "bincode", "blake3", "bv", @@ -4237,49 +4604,60 @@ dependencies = [ "fnv", "im", "index_list", - "itertools", + "itertools 0.12.1", "lazy_static", + "libc", "log", - "lru", "lz4", "memmap2", "mockall", "modular-bitfield", - "num-derive 0.4.2", + "num-derive", "num-traits", "num_cpus", - "num_enum 0.7.3", - "ouroboros", + "num_enum", "percentage", "qualifier_attr", "rand 0.8.5", "rayon", "regex", - "rustc_version", "serde", "serde_derive", "serde_json", + "serde_with", "solana-accounts-db", "solana-address-lookup-table-program", "solana-bpf-loader-program", "solana-bucket-map", + "solana-compute-budget", "solana-compute-budget-program", "solana-config-program", "solana-cost-model", - "solana-frozen-abi", - "solana-frozen-abi-macro", + "solana-feature-set", + "solana-fee", + "solana-inline-spl", + "solana-lattice-hash", "solana-loader-v4-program", "solana-measure", "solana-metrics", "solana-perf", + "solana-program", "solana-program-runtime", "solana-rayon-threadlimit", + "solana-runtime-transaction", "solana-sdk", "solana-stake-program", + "solana-svm", + "solana-svm-rent-collector", + "solana-svm-transaction", "solana-system-program", + "solana-timings", + "solana-transaction-status", "solana-version", "solana-vote", "solana-vote-program", + "solana-zk-elgamal-proof-program", + "solana-zk-sdk", "solana-zk-token-proof-program", "solana-zk-token-sdk", "static_assertions", @@ -4288,76 +4666,117 @@ dependencies = [ "symlink", "tar", "tempfile", - "thiserror", + "thiserror 1.0.69", "zstd", ] +[[package]] +name = "solana-runtime-transaction" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01e1757d4473c7a2f462d2ce5f3cb5689145cfbde3a6b12161a49e497633ab85" +dependencies = [ + "agave-transaction-view", + "log", + "solana-builtins-default-costs", + "solana-compute-budget", + "solana-pubkey", + "solana-sdk", + "solana-svm-transaction", + "thiserror 1.0.69", +] + +[[package]] +name = "solana-sanitize" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "203b90994371db8cade8e885f74ec9f68ee02a32b25d514594158b2551a4e5ed" + [[package]] name = "solana-sdk" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b3f2080eddef6552fde7f149c429cf05b9bb0605a068b0d28e19d793e24df4" +checksum = "524604d94185c189616296e5b7da1014cc96d1e446bd2b26f247f00708b9225a" dependencies = [ - "assert_matches", - "base64 0.21.7", "bincode", "bitflags 2.6.0", "borsh 1.5.1", "bs58", "bytemuck", + "bytemuck_derive", "byteorder", "chrono", - "derivation-path", "digest 0.10.7", "ed25519-dalek", "ed25519-dalek-bip32", - "generic-array", + "getrandom 0.1.16", "hmac 0.12.1", - "itertools", + "itertools 0.12.1", "js-sys", "lazy_static", "libsecp256k1", "log", "memmap2", - "num-derive 0.4.2", + "num-derive", "num-traits", - "num_enum 0.7.3", - "pbkdf2 0.11.0", - "qstring", - "qualifier_attr", + "num_enum", + "pbkdf2", "rand 0.7.3", "rand 0.8.5", - "rustc_version", - "rustversion", "serde", "serde_bytes", "serde_derive", "serde_json", "serde_with", "sha2 0.10.8", - "sha3 0.10.8", + "sha3", "siphasher", - "solana-frozen-abi", - "solana-frozen-abi-macro", - "solana-logger", + "solana-account", + "solana-bn254", + "solana-decode-error", + "solana-derivation-path", + "solana-feature-set", + "solana-inflation", + "solana-instruction", + "solana-native-token", + "solana-packet", + "solana-precompile-error", "solana-program", + "solana-program-memory", + "solana-pubkey", + "solana-sanitize", "solana-sdk-macro", - "thiserror", - "uriparse", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-short-vec", + "solana-signature", + "solana-transaction-error", + "thiserror 1.0.69", "wasm-bindgen", ] [[package]] name = "solana-sdk-macro" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8613ca80150f7e277e773620ba65d2c5fcc3a08eb8026627d601421ab43aef" +checksum = "1bd2265b93dce9d3dcf9f395abf1a85b5e06e4da4aa60ca147620003ac3abc67" dependencies = [ "bs58", "proc-macro2", "quote", - "rustversion", - "syn 2.0.77", + "syn 2.0.90", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2eef5a00a75648273c3fb6e3d85b0c8c02fcc1e36c4271664dcc39b6b128d41" +dependencies = [ + "borsh 1.5.1", + "libsecp256k1", + "solana-define-syscall", + "thiserror 1.0.69", ] [[package]] @@ -4368,13 +4787,14 @@ checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" [[package]] name = "solana-send-transaction-service" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff268c2c8a9490acfe40daeb650067e053684167c371d6d02a3bc3ad701d4c1f" +checksum = "8dc6adaa31bdaab1e5f8932575e75160f4806553ab5e15e552c258dfe1d5594b" dependencies = [ "crossbeam-channel", "log", "solana-client", + "solana-connection-cache", "solana-measure", "solana-metrics", "solana-runtime", @@ -4382,73 +4802,217 @@ dependencies = [ "solana-tpu-client", ] +[[package]] +name = "solana-serde-varint" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aeb51d3c20e2a61db0ef72617f3b8c9207a342a867af454a95f17add9f6c262" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-serialize-utils" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cfb0b57c6a431fb15ff33053caadb6c36aed4e1ce74bea9adfc459a710b3626" +dependencies = [ + "solana-instruction", + "solana-pubkey", + "solana-sanitize", +] + +[[package]] +name = "solana-sha256-hasher" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd115f3a1136314b0183235080d29023530c3a0a5df60505fdb7ea620eff9fd6" +dependencies = [ + "sha2 0.10.8", + "solana-define-syscall", + "solana-hash", +] + +[[package]] +name = "solana-short-vec" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08e55330b694db1139dcdf2a1ea7781abe8bd994dec2ab29e36abfd06e4e9274" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad9784d110f195a3a4fe423479d18f05b01a1c380a1430644a3b3038fdbe2f0" +dependencies = [ + "bs58", + "ed25519-dalek", + "generic-array", + "rand 0.8.5", + "serde", + "serde_derive", + "solana-sanitize", +] + +[[package]] +name = "solana-slot-hashes" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d216c0ebf00e95acaf2b1e227e6cc900a5ce50fb81fa0743272851e88a788d" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", +] + +[[package]] +name = "solana-slot-history" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88cbcdf767891c6a40116a5ef8f7241000f074ece4ba80c8f00b4f62705fc8a4" +dependencies = [ + "bv", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-stable-layout" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a5305ca88fb5deb219cd88f04e24f3a131769417d7fcb11a8da1126a8f98d23" +dependencies = [ + "solana-instruction", + "solana-pubkey", +] + [[package]] name = "solana-stake-program" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22aaa33150c76b5c2d11b31b8e7fceb9c147ecf40ae9050af34c619a5bf4ff3f" +checksum = "c8bb1a59fdd929becddfaed9ec33a1ca4db853f45ae85e14e4f4054a875fc41d" dependencies = [ "bincode", "log", - "rustc_version", "solana-config-program", + "solana-feature-set", + "solana-log-collector", "solana-program-runtime", "solana-sdk", + "solana-type-overrides", "solana-vote-program", ] [[package]] name = "solana-streamer" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "979d470dd7c589679a2e036078921989a2563f333b73b31e2fdceb09a6d55a29" +checksum = "ff771524872781eca074e0ba221d72b07fa0800cc1a7ffa400a9eb3e125fb922" dependencies = [ "async-channel", "bytes", "crossbeam-channel", + "dashmap", + "futures", "futures-util", + "governor", "histogram", - "indexmap 2.5.0", - "itertools", + "indexmap", + "itertools 0.12.1", "libc", "log", "nix", "pem", "percentage", - "pkcs8", "quinn", "quinn-proto", "rand 0.8.5", - "rcgen", - "rustls", + "rustls 0.23.20", "smallvec", + "socket2", + "solana-measure", "solana-metrics", "solana-perf", "solana-sdk", - "thiserror", - "tokio", - "x509-parser", + "solana-transaction-metrics-tracker", + "thiserror 1.0.69", + "tokio", + "tokio-util 0.7.12", + "x509-parser", +] + +[[package]] +name = "solana-svm" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f3b139a001effc93295b693437013f365785fab04dcf2fa679164af4206ec8" +dependencies = [ + "itertools 0.12.1", + "log", + "percentage", + "serde", + "serde_derive", + "solana-bpf-loader-program", + "solana-compute-budget", + "solana-feature-set", + "solana-fee", + "solana-loader-v4-program", + "solana-log-collector", + "solana-measure", + "solana-program-runtime", + "solana-runtime-transaction", + "solana-sdk", + "solana-svm-rent-collector", + "solana-svm-transaction", + "solana-system-program", + "solana-timings", + "solana-type-overrides", + "solana-vote", + "thiserror 1.0.69", +] + +[[package]] +name = "solana-svm-rent-collector" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e7068d6cc69c730190c96b87b106afd42cde203cf56164106792778cd0aaeb" +dependencies = [ + "solana-sdk", +] + +[[package]] +name = "solana-svm-transaction" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38a8533576cb7beca4a44b976ac27df9865bbf8c4cbca2ee8f4f3469cdd8175f" +dependencies = [ + "solana-sdk", ] [[package]] name = "solana-system-program" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "873b17e54d30a7834e5b2224351fb277e0608e40261e9a408d3706737d2a61f8" +checksum = "242634cdc1eacaa83738cc100fdd583eb88f99cc2edcc900c8ebe57d77af51b1" dependencies = [ "bincode", "log", "serde", "serde_derive", + "solana-log-collector", "solana-program-runtime", "solana-sdk", + "solana-type-overrides", ] [[package]] name = "solana-thin-client" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "851b9ae239d098c766aee3558330cc16edd0524c9cf3f9cf7c64f53b1024d507" +checksum = "10314ae3e0889cf38140902862d2c2ea481895c82c19f51dc4457b7dfa3aa6d0" dependencies = [ "bincode", "log", @@ -4459,40 +5023,78 @@ dependencies = [ "solana-sdk", ] +[[package]] +name = "solana-timings" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a8e2f926d488c1e2a65cbc05544dcb68cfa88deb4d50f89db5bfbda7ff2419" +dependencies = [ + "eager", + "enum-iterator", + "solana-sdk", +] + [[package]] name = "solana-tpu-client" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a7a7e5a522fe5333fcb47e02fb7da73ff614d917754167937b5523c383ce161" +checksum = "516cbed8800cd36fb3ecc9a65df1e76bf8251929aa32e9b10497e8d6612de605" dependencies = [ "async-trait", "bincode", "futures-util", - "indexmap 2.5.0", + "indexmap", "indicatif", "log", "rayon", "solana-connection-cache", "solana-measure", - "solana-metrics", "solana-pubsub-client", "solana-rpc-client", "solana-rpc-client-api", "solana-sdk", - "thiserror", + "thiserror 1.0.69", "tokio", ] +[[package]] +name = "solana-transaction-error" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a4bea6d80b34fe6e785d19bf928fe103928d1f6c9935ec23bb6a9d4d7a33d2" +dependencies = [ + "serde", + "serde_derive", + "solana-instruction", + "solana-sanitize", +] + +[[package]] +name = "solana-transaction-metrics-tracker" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0b668c986a83e6b2eb8f130039045b54abc37ee821853250755386d26c1c668" +dependencies = [ + "base64 0.22.1", + "bincode", + "lazy_static", + "log", + "rand 0.8.5", + "solana-perf", + "solana-sdk", + "solana-short-vec", +] + [[package]] name = "solana-transaction-status" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51be349fb9301d2a0fdd0b9ba5341e5f72bf4900ca4c0ede04748bc9038d15e8" +checksum = "e3e8ed5bf2511c45b923de25482407c9a2eb56af73dba52c19db76df4dd35cba" dependencies = [ "Inflector", - "base64 0.21.7", + "base64 0.22.1", "bincode", - "borsh 0.10.4", + "borsh 1.5.1", "bs58", "lazy_static", "log", @@ -4501,94 +5103,165 @@ dependencies = [ "serde_json", "solana-account-decoder", "solana-sdk", + "solana-transaction-status-client-types", "spl-associated-token-account", "spl-memo", - "spl-token", + "spl-token 6.0.0", "spl-token-2022", - "thiserror", + "spl-token-group-interface", + "spl-token-metadata-interface", + "thiserror 1.0.69", +] + +[[package]] +name = "solana-transaction-status-client-types" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fb35fb678fec581e9bdf6350d2c7f5829951a6280038fc06949b1589a9605e1" +dependencies = [ + "base64 0.22.1", + "bincode", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types", + "solana-sdk", + "solana-signature", + "thiserror 1.0.69", +] + +[[package]] +name = "solana-type-overrides" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2066f25d460d63801f91436c2640aaba4f2dc95aa18fe1e76f7f2c063e981d4e" +dependencies = [ + "lazy_static", + "rand 0.8.5", ] [[package]] name = "solana-udp-client" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3274b4bfccd57ecffcf4037cd09fc61777633e0d0c5f8b76abcaa10ee83f3ae5" +checksum = "95ec0cbc2d5e3379fafb2c1493f2358f07c09e76e2081c44e3a8c36da12fbd40" dependencies = [ "async-trait", "solana-connection-cache", "solana-net-utils", "solana-sdk", "solana-streamer", - "thiserror", + "thiserror 1.0.69", "tokio", ] [[package]] name = "solana-version" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf45873439f73420f60a5e0f87b529923c3489d24a228d5eb8f5ce6955bdc1b" +checksum = "7310708b642fb83c04f44934509f4f149ffd69d0cd4cf76d9645c991177d7ea0" dependencies = [ - "log", - "rustc_version", "semver", "serde", "serde_derive", - "solana-frozen-abi", - "solana-frozen-abi-macro", - "solana-sdk", + "solana-feature-set", + "solana-sanitize", + "solana-serde-varint", ] [[package]] name = "solana-vote" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54cb2827041a2acb79e3855e7310466d9bef71650e2304994076b209eaf4d9f" +checksum = "5ab46788981765ee706094ca53ad8421aae0286a6b948e892fa7db88992a5373" dependencies = [ - "crossbeam-channel", - "itertools", + "itertools 0.12.1", "log", - "rustc_version", "serde", "serde_derive", - "solana-frozen-abi", - "solana-frozen-abi-macro", "solana-sdk", - "solana-vote-program", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "solana-vote-program" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7c7525bda137bbb9bc0dc967a4ffca82786147eb2d1efbf76a8dc52978f0b8" +checksum = "637cadc921725d1804a451ea7d2dff83310a12b75e0b6c83a8bb67ebc02d10f1" dependencies = [ "bincode", "log", - "num-derive 0.4.2", + "num-derive", "num-traits", - "rustc_version", "serde", "serde_derive", - "solana-frozen-abi", - "solana-frozen-abi-macro", + "solana-feature-set", "solana-metrics", "solana-program", "solana-program-runtime", "solana-sdk", - "thiserror", + "thiserror 1.0.69", +] + +[[package]] +name = "solana-zk-elgamal-proof-program" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47f5ac026a972c9cbc6bd0f72f692f85ff9ceec961fc4bcb1f2550e6387e962c" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-log-collector", + "solana-program-runtime", + "solana-sdk", + "solana-zk-sdk", +] + +[[package]] +name = "solana-zk-sdk" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18c2d96f65cb033f4dc16d3a1b085f8af0ea38012c514a8f65b9b6d75bc9339f" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", + "js-sys", + "lazy_static", + "merlin", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path", + "solana-program", + "solana-sdk", + "subtle", + "thiserror 1.0.69", + "wasm-bindgen", + "zeroize", ] [[package]] name = "solana-zk-token-proof-program" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce8bf8a6d43db385a2beb324110282ae8140a4a040d39f3a0870c43df24c5055" +checksum = "83029f0fac09633fc4463dd5a7d13959d1825dccf77889c6e617e2b1265fb2f1" dependencies = [ "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", + "solana-feature-set", + "solana-log-collector", "solana-program-runtime", "solana-sdk", "solana-zk-token-sdk", @@ -4596,58 +5269,54 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.18.23" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a57b2f269f24088b6b8e426de05e5c1faa6b5d6f26175c06eb80df96ec685e" +checksum = "ed293089d8eebd6b5c1b53ee4ad6817889fea254274ddb34cb01ad35a2f817cb" dependencies = [ "aes-gcm-siv", - "base64 0.21.7", + "base64 0.22.1", "bincode", "bytemuck", + "bytemuck_derive", "byteorder", - "curve25519-dalek", - "getrandom 0.1.16", - "itertools", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", "lazy_static", "merlin", - "num-derive 0.4.2", + "num-derive", "num-traits", - "rand 0.7.3", + "rand 0.8.5", "serde", + "serde_derive", "serde_json", - "sha3 0.9.1", + "sha3", + "solana-curve25519", + "solana-derivation-path", "solana-program", "solana-sdk", "subtle", - "thiserror", + "thiserror 1.0.69", "zeroize", ] [[package]] name = "solana_rbpf" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da5d083187e3b3f453e140f292c09186881da8a02a7b5e27f645ee26de3d9cc5" +checksum = "1c1941b5ef0c3ce8f2ac5dd984d0fb1a97423c4ff2a02eec81e3913f02e2ac2b" dependencies = [ "byteorder", - "combine", - "goblin", + "combine 3.8.1", "hash32", "libc", "log", "rand 0.8.5", "rustc-demangle", "scroll", - "thiserror", + "thiserror 1.0.69", "winapi", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -4655,36 +5324,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] -name = "spki" -version = "0.5.4" +name = "spinning_top" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" dependencies = [ - "base64ct", - "der", + "lock_api", ] [[package]] name = "spl-associated-token-account" -version = "2.3.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "992d9c64c2564cc8f63a4b508bf3ebcdf2254b0429b13cd1d31adb6162432a5f" +checksum = "68034596cf4804880d265f834af1ff2f821ad5293e41fa0f8f59086c181fc38e" dependencies = [ "assert_matches", - "borsh 0.10.4", - "num-derive 0.4.2", + "borsh 1.5.1", + "num-derive", "num-traits", "solana-program", - "spl-token", + "spl-token 6.0.0", "spl-token-2022", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "spl-discriminator" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" +checksum = "a38ea8b6dedb7065887f12d62ed62c1743aa70749e8558f963609793f6fb12bc" dependencies = [ "bytemuck", "solana-program", @@ -4693,45 +5361,46 @@ dependencies = [ [[package]] name = "spl-discriminator-derive" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" +checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" dependencies = [ "quote", "spl-discriminator-syn", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] name = "spl-discriminator-syn" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fea7be851bd98d10721782ea958097c03a0c2a07d8d4997041d0ece6319a63" +checksum = "8c1f05593b7ca9eac7caca309720f2eafb96355e037e6d373b909a80fe7b69b9" dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.77", - "thiserror", + "syn 2.0.90", + "thiserror 1.0.69", ] [[package]] name = "spl-memo" -version = "4.0.0" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" +checksum = "a0dba2f2bb6419523405d21c301a32c9f9568354d4742552e7972af801f4bdb3" dependencies = [ "solana-program", ] [[package]] name = "spl-pod" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" +checksum = "c704c88fc457fa649ba3aabe195c79d885c3f26709efaddc453c8de352c90b87" dependencies = [ - "borsh 0.10.4", + "borsh 1.5.1", "bytemuck", + "bytemuck_derive", "solana-program", "solana-zk-token-sdk", "spl-program-error", @@ -4739,34 +5408,34 @@ dependencies = [ [[package]] name = "spl-program-error" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" +checksum = "d7b28bed65356558133751cc32b48a7a5ddfc59ac4e941314630bbed1ac10532" dependencies = [ - "num-derive 0.4.2", + "num-derive", "num-traits", "solana-program", "spl-program-error-derive", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "spl-program-error-derive" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1845dfe71fd68f70382232742e758557afe973ae19e6c06807b2c30f5d5cb474" +checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" dependencies = [ "proc-macro2", "quote", "sha2 0.10.8", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] name = "spl-tlv-account-resolution" -version = "0.5.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "615d381f48ddd2bb3c57c7f7fb207591a2a05054639b18a62e785117dd7a8683" +checksum = "37a75a5f0fcc58126693ed78a17042e9dc53f07e357d6be91789f7d62aff61a4" dependencies = [ "bytemuck", "solana-program", @@ -4778,48 +5447,63 @@ dependencies = [ [[package]] name = "spl-token" -version = "4.0.0" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e9e171cbcb4b1f72f6d78ed1e975cb467f56825c27d09b8dd2608e4e7fc8b3b" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-program", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" +checksum = "70a0f06ac7f23dc0984931b1fe309468f14ea58e32660439c1cef19456f5d0e3" dependencies = [ "arrayref", "bytemuck", - "num-derive 0.3.3", + "num-derive", "num-traits", - "num_enum 0.6.1", + "num_enum", "solana-program", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "spl-token-2022" -version = "1.0.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d697fac19fd74ff472dfcc13f0b442dd71403178ce1de7b5d16f83a33561c059" +checksum = "d9c10f3483e48679619c76598d4e4aebb955bc49b0a5cc63323afbf44135c9bf" dependencies = [ "arrayref", "bytemuck", - "num-derive 0.4.2", + "num-derive", "num-traits", - "num_enum 0.7.3", + "num_enum", "solana-program", "solana-security-txt", "solana-zk-token-sdk", "spl-memo", "spl-pod", - "spl-token", + "spl-token 6.0.0", "spl-token-group-interface", "spl-token-metadata-interface", "spl-transfer-hook-interface", "spl-type-length-value", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "spl-token-group-interface" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b889509d49fa74a4a033ca5dae6c2307e9e918122d97e58562f5c4ffa795c75d" +checksum = "df8752b85a5ecc1d9f3a43bce3dd9a6a053673aacf5deb513d1cbb88d3534ffd" dependencies = [ "bytemuck", "solana-program", @@ -4830,11 +5514,11 @@ dependencies = [ [[package]] name = "spl-token-metadata-interface" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" +checksum = "c6c2318ddff97e006ed9b1291ebec0750a78547f870f62a69c56fe3b46a5d8fc" dependencies = [ - "borsh 0.10.4", + "borsh 1.5.1", "solana-program", "spl-discriminator", "spl-pod", @@ -4844,9 +5528,9 @@ dependencies = [ [[package]] name = "spl-transfer-hook-interface" -version = "0.4.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aabdb7c471566f6ddcee724beb8618449ea24b399e58d464d6b5bc7db550259" +checksum = "a110f33d941275d9f868b96daaa993f1e73b6806cc8836e43075b4d3ad8338a7" dependencies = [ "arrayref", "bytemuck", @@ -4860,9 +5544,9 @@ dependencies = [ [[package]] name = "spl-type-length-value" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" +checksum = "bdcd73ec187bc409464c60759232e309f83b52a18a9c5610bf281c9c6432918c" dependencies = [ "bytemuck", "solana-program", @@ -4877,18 +5561,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" @@ -4919,9 +5591,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.4.1" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symlink" @@ -4942,9 +5614,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -4960,7 +5632,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -5029,7 +5701,7 @@ dependencies = [ "serde", "static_assertions", "tarpc-plugins", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-serde", "tokio-util 0.6.10", @@ -5048,11 +5720,20 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "task-local-extensions" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba323866e5d033818e3240feeb9f7db2c4296674e4d9e16b97b7bf8f490434e8" +dependencies = [ + "pin-utils", +] + [[package]] name = "tempfile" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -5094,7 +5775,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -5105,43 +5786,48 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "test-case-core", ] [[package]] -name = "textwrap" -version = "0.11.0" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "unicode-width", + "thiserror-impl 1.0.69", ] [[package]] -name = "textwrap" -version = "0.16.1" +name = "thiserror" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" +dependencies = [ + "thiserror-impl 2.0.9", +] [[package]] -name = "thiserror" -version = "1.0.64" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "thiserror-impl", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -5185,25 +5871,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny-bip39" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" -dependencies = [ - "anyhow", - "hmac 0.8.1", - "once_cell", - "pbkdf2 0.4.0", - "rand 0.7.3", - "rustc-hash", - "sha2 0.9.9", - "thiserror", - "unicode-normalization", - "wasm-bindgen", - "zeroize", -] - [[package]] name = "tinyvec" version = "1.8.0" @@ -5232,12 +5899,13 @@ name = "token-program" version = "0.0.0" dependencies = [ "assert_matches", + "mollusk-svm", "pinocchio", "pinocchio-log", "pinocchio-pubkey", "solana-program-test", "solana-sdk", - "spl-token", + "spl-token 4.0.2", "test-case", "token-interface", ] @@ -5268,7 +5936,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -5277,7 +5945,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls", + "rustls 0.21.12", "tokio", ] @@ -5316,7 +5984,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls", + "rustls 0.21.12", "tokio", "tokio-rustls", "tungstenite", @@ -5366,26 +6034,15 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.5.0", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.5.0", + "indexmap", "toml_datetime", - "winnow 0.6.20", + "winnow", ] [[package]] @@ -5414,7 +6071,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] @@ -5470,9 +6127,9 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls", + "rustls 0.21.12", "sha1", - "thiserror", + "thiserror 1.0.69", "url", "utf-8", "webpki-roots 0.24.0", @@ -5484,6 +6141,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicase" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -5519,11 +6182,11 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "generic-array", + "crypto-common", "subtle", ] @@ -5536,12 +6199,6 @@ dependencies = [ "void", ] -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" @@ -5581,12 +6238,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.5" @@ -5632,9 +6283,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -5643,16 +6294,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "wasm-bindgen-shared", ] @@ -5670,9 +6320,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5680,22 +6330,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "web-sys" @@ -5707,13 +6357,32 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-root-certs" +version = "0.26.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd5da49bdf1f30054cfe0b8ce2958b8fbeb67c4d82c8967a598af481bef255c" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" dependencies = [ - "rustls-webpki", + "rustls-webpki 0.101.7", ] [[package]] @@ -5910,15 +6579,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.20" @@ -5952,7 +6612,7 @@ dependencies = [ "nom", "oid-registry", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -5967,15 +6627,6 @@ dependencies = [ "rustix", ] -[[package]] -name = "yasna" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" -dependencies = [ - "time", -] - [[package]] name = "zerocopy" version = "0.7.35" @@ -5994,14 +6645,14 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] name = "zeroize" -version = "1.3.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -6014,25 +6665,24 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.90", ] [[package]] name = "zstd" -version = "0.11.2+zstd.1.5.2" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" dependencies = [ - "libc", "zstd-sys", ] diff --git a/program/Cargo.toml b/program/Cargo.toml index 0ef9320..baf36cf 100644 --- a/program/Cargo.toml +++ b/program/Cargo.toml @@ -25,7 +25,8 @@ token-interface = { version = "^0", path = "../interface" } [dev-dependencies] assert_matches = "1.5.0" -solana-program-test = "~1.18" -solana-sdk = "~1.18" +mollusk-svm = { version = "0.0.13", git = "https://github.com/buffalojoec/mollusk.git" } +solana-program-test = "2.1.0" +solana-sdk = "2.1.0" spl-token = { version="^4", features=["no-entrypoint"] } test-case = "3.3.1" diff --git a/program/tests/initialize_mint.rs b/program/tests/initialize_mint.rs index f99ade1..4138446 100644 --- a/program/tests/initialize_mint.rs +++ b/program/tests/initialize_mint.rs @@ -20,7 +20,7 @@ use token_interface::state::mint::Mint; #[test_case::test_case(TOKEN_PROGRAM_ID ; "p-token")] #[tokio::test] async fn initialize_mint(token_program: Pubkey) { - let mut context = ProgramTest::new("token_program", TOKEN_PROGRAM_ID, None) + let context = ProgramTest::new("token_program", TOKEN_PROGRAM_ID, None) .start_with_context() .await; diff --git a/program/tests/initialize_mint2.rs b/program/tests/initialize_mint2.rs index 1b8c24f..50eafea 100644 --- a/program/tests/initialize_mint2.rs +++ b/program/tests/initialize_mint2.rs @@ -20,7 +20,7 @@ use token_interface::state::mint::Mint; #[test_case::test_case(TOKEN_PROGRAM_ID ; "p-token")] #[tokio::test] async fn initialize_mint2(token_program: Pubkey) { - let mut context = ProgramTest::new("token_program", TOKEN_PROGRAM_ID, None) + let context = ProgramTest::new("token_program", TOKEN_PROGRAM_ID, None) .start_with_context() .await; diff --git a/program/tests/initialize_multisig.rs b/program/tests/initialize_multisig.rs index 574554d..66fe40b 100644 --- a/program/tests/initialize_multisig.rs +++ b/program/tests/initialize_multisig.rs @@ -17,7 +17,7 @@ use spl_token::state::Multisig; #[test_case::test_case(TOKEN_PROGRAM_ID ; "p-token")] #[tokio::test] async fn initialize_multisig(token_program: Pubkey) { - let mut context = ProgramTest::new("token_program", TOKEN_PROGRAM_ID, None) + let context = ProgramTest::new("token_program", TOKEN_PROGRAM_ID, None) .start_with_context() .await; diff --git a/program/tests/initialize_multisig2.rs b/program/tests/initialize_multisig2.rs index e1d95b8..2745518 100644 --- a/program/tests/initialize_multisig2.rs +++ b/program/tests/initialize_multisig2.rs @@ -17,7 +17,7 @@ use spl_token::state::Multisig; #[test_case::test_case(TOKEN_PROGRAM_ID ; "p-token")] #[tokio::test] async fn initialize_multisig2(token_program: Pubkey) { - let mut context = ProgramTest::new("token_program", TOKEN_PROGRAM_ID, None) + let context = ProgramTest::new("token_program", TOKEN_PROGRAM_ID, None) .start_with_context() .await; diff --git a/program/tests/processor.rs b/program/tests/processor.rs new file mode 100644 index 0000000..cea9ac5 --- /dev/null +++ b/program/tests/processor.rs @@ -0,0 +1,7030 @@ +#![cfg(feature = "test-sbf")] + +//! Program state processor tests + +use { + mollusk_svm::{ + result::{Check, InstructionResult}, + Mollusk, + }, + solana_sdk::{ + account::{create_account_for_test, Account as SolanaAccount, AccountSharedData}, + instruction::Instruction, + program_error::ProgramError, + program_option::COption, + program_pack::Pack, + pubkey::Pubkey, + rent::Rent, + }, + spl_token::{ + error::TokenError, + instruction::{ + approve, approve_checked, initialize_account, initialize_mint, initialize_mint2, + initialize_multisig, mint_to, mint_to_checked, revoke, set_authority, transfer, + transfer_checked, AuthorityType, + }, + state::{Account, AccountState, Mint, Multisig}, + }, + std::collections::HashSet, +}; + +/// The name of the token program `.so` file. +const TOKEN_PROGRAM_NAME: &str = "token_program"; + +/// The ID of the token program used in the instruction constructors. +/// +/// In general this should be the same as the `spl_token::id()` constant, since +/// the instruction construction functions are designed to work with the +/// `spl_token`. This value then is replaced by [`TARGET_TOKEN_PROGRAM_ID`] when +/// the instruction is processed by `mollusk` helper. +const INSTRUCTION_TOKEN_PROGRAM_ID: Pubkey = spl_token::id(); + +/// The ID of the token program that will execute the instruction. +const TARGET_TOKEN_PROGRAM_ID: Pubkey = Pubkey::new_from_array(token_interface::program::ID); + +/// A tuple of an instruction and the accounts it references. +type InstructionPack<'a> = (Instruction, Vec<&'a SolanaAccount>); + +/// Process a list of instructions using mollusk. +fn do_process_instructions( + instructions: &[InstructionPack], + checks: &[Check], +) -> InstructionResult { + do_process_instructions_with_pre_instructions(None, instructions, checks) +} + +/// Process a list of instructions using mollusk with a pre-defined set of +/// "setup" instructions. +fn do_process_instructions_with_pre_instructions( + pre_instructions: Option<&[InstructionPack]>, + instructions: &[InstructionPack], + checks: &[Check], +) -> InstructionResult { + // Track the accounts that have been set up. + let mut cached_accounts = HashSet::new(); + // List of instructions to process. + let mut tx_instructions = Vec::new(); + // List of accounts to process. + let mut tx_accounts = Vec::new(); + + // Process pre-instructions. + if let Some(pre_instructions) = pre_instructions { + pre_instructions.iter().for_each(|(instruction, accounts)| { + instruction + .accounts + .iter() + .zip(accounts) + .map(|(account_meta, account)| { + ( + account_meta.pubkey, + AccountSharedData::from((*account).clone()), + ) + }) + .for_each(|(pubkey, account)| { + if !cached_accounts.contains(&pubkey) { + cached_accounts.insert(pubkey); + tx_accounts.push((pubkey, account)); + } + }); + let mut ix = instruction.clone(); + ix.program_id = TARGET_TOKEN_PROGRAM_ID; + tx_instructions.push(ix); + }); + } + + // Process instructions. + instructions.iter().for_each(|(instruction, accounts)| { + instruction + .accounts + .iter() + .zip(accounts) + .map(|(account_meta, account)| { + ( + account_meta.pubkey, + AccountSharedData::from((*account).clone()), + ) + }) + .for_each(|(pubkey, account)| { + if !cached_accounts.contains(&pubkey) { + cached_accounts.insert(pubkey); + tx_accounts.push((pubkey, account)); + } + }); + let mut ix = instruction.clone(); + ix.program_id = TARGET_TOKEN_PROGRAM_ID; + tx_instructions.push(ix); + }); + + let mollusk = Mollusk::new(&TARGET_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_NAME); + mollusk.process_and_validate_instruction_chain( + tx_instructions.as_slice(), + tx_accounts.as_slice(), + checks, + ) +} + +fn account_minimum_balance() -> u64 { + Rent::default().minimum_balance(Account::get_packed_len()) +} + +fn mint_minimum_balance() -> u64 { + Rent::default().minimum_balance(Mint::get_packed_len()) +} + +fn multisig_minimum_balance() -> u64 { + Rent::default().minimum_balance(Multisig::get_packed_len()) +} + +fn rent_sysvar() -> SolanaAccount { + create_account_for_test(&Rent::default()) +} + +#[test] +fn test_initialize_mint() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let owner_key = Pubkey::new_unique(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = SolanaAccount::new(42, Mint::get_packed_len(), &program_id); + let mint2_key = Pubkey::new_unique(); + let mint2_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let rent_sysvar = rent_sysvar(); + + // mint is not rent exempt + do_process_instructions( + &[( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + )], + &[Check::err(TokenError::NotRentExempt.into())], + ); + + mint_account.lamports = mint_minimum_balance(); + + // create new mint + do_process_instructions( + &[( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + )], + &[Check::success()], + ); + + // create twice + do_process_instructions( + &[ + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + ], + &[Check::err(TokenError::AlreadyInUse.into())], + ); + + // create another mint that can freeze + do_process_instructions( + &[( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint2_key, + &owner_key, + Some(&owner_key), + 2, + ) + .unwrap(), + vec![&mint2_account, &rent_sysvar], + )], + &[ + // Account successfully re-initialized. + Check::success(), + // mint authority is set + Check::account(&mint2_key) + .data_slice(46, &[1, 0, 0, 0]) + .build(), + // mint authority matches owner + Check::account(&mint2_key) + .data_slice(50, owner_key.as_ref()) + .build(), + ], + ); +} + +#[test] +fn test_initialize_mint2() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let owner_key = Pubkey::new_unique(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = SolanaAccount::new(42, Mint::get_packed_len(), &program_id); + let mint2_key = Pubkey::new_unique(); + let mut mint2_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + + // mint is not rent exempt + do_process_instructions( + &[( + initialize_mint2( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account], + )], + &[Check::err(TokenError::NotRentExempt.into())], + ); + + mint_account.lamports = mint_minimum_balance(); + + // create new mint + do_process_instructions( + &[( + initialize_mint2( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account], + )], + &[Check::success()], + ); + + // create twice + do_process_instructions( + &[ + ( + initialize_mint2( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account], + ), + ( + initialize_mint2( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account], + ), + ], + &[Check::err(TokenError::AlreadyInUse.into())], + ); + + // create another mint that can freeze + do_process_instructions( + &[( + initialize_mint2( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint2_key, + &owner_key, + Some(&owner_key), + 2, + ) + .unwrap(), + vec![&mut mint2_account], + )], + &[ + // Account successfully re-initialized. + Check::success(), + // mint authority is set + Check::account(&mint2_key) + .data_slice(46, &[1, 0, 0, 0]) + .build(), + // mint authority matches owner + Check::account(&mint2_key) + .data_slice(50, owner_key.as_ref()) + .build(), + ], + ); +} + +#[test] +fn test_initialize_mint_account() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new(42, Account::get_packed_len(), &program_id); + let owner_key = Pubkey::new_unique(); + let owner_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let rent_sysvar = rent_sysvar(); + + // account is not rent exempt + do_process_instructions( + &[( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + )], + &[Check::err(TokenError::NotRentExempt.into())], + ); + + account_account.lamports = account_minimum_balance(); + + // mint is not valid (not initialized) + do_process_instructions( + &[( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + )], + &[Check::err(TokenError::InvalidMint.into())], + ); + + // create mint + do_process_instructions( + &[( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + )], + &[Check::success()], + ); + + // mint not owned by program + let not_program_id = Pubkey::new_unique(); + mint_account.owner = not_program_id; + + do_process_instructions( + &[( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + )], + &[Check::err(ProgramError::IncorrectProgramId)], + ); + + mint_account.owner = program_id; + + // create account + do_process_instructions( + &[ + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + ], + &[Check::success()], + ); + + // create twice + do_process_instructions( + &[ + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + ], + &[Check::err(TokenError::AlreadyInUse.into())], + ); +} + +#[test] +fn test_transfer_dups() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let account1_key = Pubkey::new_unique(); + let account1_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + //let mut account1_info: AccountInfo = (&account1_key, true, &mut + // account1_account).into(); + let account2_key = Pubkey::new_unique(); + let account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + //let mut account2_info: AccountInfo = (&account2_key, false, &mut + // account2_account).into(); + let account3_key = Pubkey::new_unique(); + let account3_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + //let account3_info: AccountInfo = (&account3_key, false, &mut + // account3_account).into(); + let account4_key = Pubkey::new_unique(); + let account4_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + //let account4_info: AccountInfo = (&account4_key, true, &mut + // account4_account).into(); + let multisig_key = Pubkey::new_unique(); + let multisig_account = SolanaAccount::new( + multisig_minimum_balance(), + Multisig::get_packed_len(), + &program_id, + ); + //let multisig_info: AccountInfo = (&multisig_key, true, &mut + // multisig_account).into(); + let owner_key = Pubkey::new_unique(); + let owner_account = SolanaAccount::default(); + //let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into(); + let mint_key = Pubkey::new_unique(); + let mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + //let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into(); + //let rent_key = solana_sdk::sysvar::rent::id(); + let rent_sysvar = rent_sysvar(); + //let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into(); + + let setup_instructions = vec![ + // create mint + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + // create account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + &mint_key, + &account1_key, + ) + .unwrap(), + vec![ + &account1_account, + &mint_account, + &account1_account, + &rent_sysvar, + ], + ), + // create another account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account2_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + // mint to account + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account1_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account1_account, &owner_account], + ), + ]; + + // source-owner transfer + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + &account2_key, + &account1_key, + &[], + 500, + ) + .unwrap(), + vec![&account1_account, &account2_account, &account1_account], + )], + &[Check::success()], + ); + + // source-owner TransferChecked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + &mint_key, + &account2_key, + &account1_key, + &[], + 500, + 2, + ) + .unwrap(), + vec![ + &account1_account, + &mint_account, + &account2_account, + &account1_account, + ], + )], + &[Check::success()], + ); + + // source-delegate transfer + let delegate_key = Pubkey::new_unique(); + let delegate_account = SolanaAccount::default(); + + let mut account = Account::unpack_unchecked(&account1_account.data).unwrap(); + account.state = AccountState::Initialized; + account.mint = mint_key; + account.amount = 1000; + account.delegated_amount = 1000; + account.delegate = COption::Some(delegate_key); + account.owner = owner_key; + let delegated_account_key = Pubkey::new_unique(); + let mut delegated_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + Account::pack(account, &mut delegated_account.data).unwrap(); + + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &delegated_account_key, + &account2_key, + &delegate_key, + &[], + 500, + ) + .unwrap(), + vec![&delegated_account, &account2_account, &delegate_account], + )], + &[Check::success()], + ); + + // source-delegate TransferChecked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &delegated_account_key, + &mint_key, + &account2_key, + &delegate_key, + &[], + 500, + 2, + ) + .unwrap(), + vec![ + &delegated_account, + &mint_account, + &account2_account, + &delegate_account, + ], + )], + &[Check::success()], + ); + + // test destination-owner transfer + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &mint_key, + &account2_key, + ) + .unwrap(), + vec![ + &account3_account, + &mint_account, + &account2_account, + &rent_sysvar, + ], + ), + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account3_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account3_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &account2_key, + &account2_key, + &[], + 500, + ) + .unwrap(), + vec![&account3_account, &account2_account, &account2_account], + ), + ], + &[Check::success()], + ); + + // destination-owner TransferChecked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &mint_key, + &account2_key, + ) + .unwrap(), + vec![ + &account3_account, + &mint_account, + &account2_account, + &rent_sysvar, + ], + ), + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account3_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account3_account, &owner_account], + ), + ( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &mint_key, + &account2_key, + &account2_key, + &[], + 500, + 2, + ) + .unwrap(), + vec![ + &account3_account, + &mint_account, + &account2_account, + &account2_account, + ], + ), + ], + &[Check::success()], + ); + + // test source-multisig signer + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + initialize_multisig( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &multisig_key, + &[&account4_key], + 1, + ) + .unwrap(), + vec![&multisig_account, &rent_sysvar, &account4_account], + ), + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account4_key, + &mint_key, + &multisig_key, + ) + .unwrap(), + vec![ + &account4_account, + &mint_account, + &multisig_account, + &rent_sysvar, + ], + ), + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account4_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account4_account, &owner_account], + ), + ], + &[Check::success()], + ); + + // source-multisig-signer transfer + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + initialize_multisig( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &multisig_key, + &[&account4_key], + 1, + ) + .unwrap(), + vec![&multisig_account, &rent_sysvar, &account4_account], + ), + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account4_key, + &mint_key, + &multisig_key, + ) + .unwrap(), + vec![ + &account4_account, + &mint_account, + &multisig_account, + &rent_sysvar, + ], + ), + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account4_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account4_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account4_key, + &account2_key, + &multisig_key, + &[&account4_key], + 500, + ) + .unwrap(), + vec![ + &account4_account, + &account2_account, + &multisig_account, + &account4_account, + ], + ), + ], + &[Check::success()], + ); + + // source-multisig-signer TransferChecked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + initialize_multisig( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &multisig_key, + &[&account4_key], + 1, + ) + .unwrap(), + vec![&multisig_account, &rent_sysvar, &account4_account], + ), + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account4_key, + &mint_key, + &multisig_key, + ) + .unwrap(), + vec![ + &account4_account, + &mint_account, + &multisig_account, + &rent_sysvar, + ], + ), + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account4_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account4_account, &owner_account], + ), + ( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account4_key, + &mint_key, + &account2_key, + &multisig_key, + &[&account4_key], + 500, + 2, + ) + .unwrap(), + vec![ + &account4_account, + &mint_account, + &account2_account, + &multisig_account, + &account4_account, + ], + ), + ], + &[Check::success()], + ); +} + +#[test] +fn test_transfer() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let account_key = Pubkey::new_unique(); + let account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account3_key = Pubkey::new_unique(); + let account3_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let delegate_key = Pubkey::new_unique(); + let delegate_account = SolanaAccount::default(); + let mismatch_key = Pubkey::new_unique(); + let mismatch_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let owner_account = SolanaAccount::default(); + let owner2_key = Pubkey::new_unique(); + let owner2_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint2_key = Pubkey::new_unique(); + let mint2_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let rent_sysvar = rent_sysvar(); + + let setup_instructions = vec![ + // create mint + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + // create account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + // create another account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account2_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + // create another account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account3_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + // mint to account + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account_account, &owner_account], + ), + // create a second mint + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint2_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint2_account, &rent_sysvar], + ), + // create mismatch account using mint2 + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mismatch_key, + &mint2_key, + &owner_key, + ) + .unwrap(), + vec![ + &mismatch_account, + &mint2_account, + &owner_account, + &rent_sysvar, + ], + ), + ]; + + // missing signer + let mut instruction = transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner_key, + &[], + 1000, + ) + .unwrap(); + instruction.accounts[2].is_signer = false; + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + instruction, + vec![&account_account, &account2_account, &owner_account], + )], + &[Check::err(ProgramError::MissingRequiredSignature)], + ); + + // mismatch mint + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mismatch_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&account_account, &mismatch_account, &owner_account], + )], + &[Check::err(TokenError::MintMismatch.into())], + ); + + // missing owner + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner2_key, + &[], + 1000, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner2_account], + )], + &[Check::err(TokenError::OwnerMismatch.into())], + ); + + // account not owned by program + let not_program_key = Pubkey::new_unique(); + let mut account = Account::unpack_unchecked(&account_account.data).unwrap(); + account.state = AccountState::Initialized; + account.mint = mint_key; + account.owner = owner_key; + let mut not_program_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + ¬_program_key, + ); + Account::pack(account, &mut not_program_account.data).unwrap(); + + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + ¬_program_key, + &account2_key, + &owner_key, + &[], + 0, + ) + .unwrap(), + vec![¬_program_account, &account2_account, &owner2_account], + )], + &[Check::err(ProgramError::IncorrectProgramId)], + ); + + // account 2 not owned by program + let mut account2 = Account::unpack_unchecked(&account_account.data).unwrap(); + account2.state = AccountState::Initialized; + account2.mint = mint_key; + account2.owner = owner_key; + let mut not_program_account2 = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + ¬_program_key, + ); + Account::pack(account2, &mut not_program_account2.data).unwrap(); + + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + ¬_program_key, + &owner_key, + &[], + 0, + ) + .unwrap(), + vec![&account_account, ¬_program_account2, &owner2_account], + )], + &[Check::err(ProgramError::IncorrectProgramId)], + ); + + // transfer + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner_account], + )], + &[Check::success()], + ); + + // insufficient funds + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner_key, + &[], + 1001, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner_account], + )], + &[Check::err(TokenError::InsufficientFunds.into())], + ); + + // transfer half back + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &account_key, + &owner_key, + &[], + 500, + ) + .unwrap(), + vec![&account2_account, &account_account, &owner_account], + ), + ], + &[Check::success()], + ); + + // incorrect decimals + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner_account], + ), + ( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &mint_key, + &account_key, + &owner_key, + &[], + 1, + 10, // <-- incorrect decimals + ) + .unwrap(), + vec![ + &account2_account, + &mint_account, + &account_account, + &owner_account, + ], + ), + ], + &[Check::err(TokenError::MintDecimalsMismatch.into())], + ); + + // incorrect mint + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner_account], + ), + ( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &account3_key, // <-- incorrect mint + &account_key, + &owner_key, + &[], + 1, + 2, + ) + .unwrap(), + vec![ + &account2_account, + &account3_account, // <-- incorrect mint + &account_account, + &owner_account, + ], + ), + ], + &[Check::err(TokenError::MintMismatch.into())], + ); + + // transfer rest with explicit decimals + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &account_key, + &owner_key, + &[], + 500, + ) + .unwrap(), + vec![&account2_account, &account_account, &owner_account], + ), + ( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &mint_key, + &account_key, + &owner_key, + &[], + 500, + 2, + ) + .unwrap(), + vec![ + &account2_account, + &mint_account, + &account_account, + &owner_account, + ], + ), + ], + &[Check::success()], + ); + /* TODO: seems to be tested already + // insufficient funds + assert_eq!( + Err(TokenError::InsufficientFunds.into()), + do_process_instruction( + transfer( + &TOKEN_PROGRAM_ID, + &account2_key, + &account_key, + &owner_key, + &[], + 1 + ) + .unwrap(), + vec![ + &mut account2_account, + &mut account_account, + &mut owner_account, + ], + ) + ); + */ + + // approve delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + )], + &[Check::success()], + ); + + // not a delegate of source account + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner2_key, // <-- incorrect owner or delegate + &[], + 1, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner2_account], + ), + ], + &[Check::err(TokenError::OwnerMismatch.into())], + ); + + // insufficient funds approved via delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &delegate_key, + &[], + 101, + ) + .unwrap(), + vec![&account_account, &account2_account, &delegate_account], + ), + ], + &[Check::err(TokenError::InsufficientFunds.into())], + ); + + // transfer via delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &delegate_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &account2_account, &delegate_account], + ), + ], + &[Check::success()], + ); + + // insufficient funds approved via delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &delegate_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &account2_account, &delegate_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &delegate_key, + &[], + 1, + ) + .unwrap(), + vec![&account_account, &account2_account, &delegate_account], + ), + ], + &[Check::err(TokenError::OwnerMismatch.into())], + ); + + // transfer rest + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &delegate_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &account2_account, &delegate_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner_key, + &[], + 900, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner_account], + ), + ], + &[Check::success()], + ); + + // approve delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &delegate_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &account2_account, &delegate_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner_key, + &[], + 900, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner_account], + ), + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ], + &[Check::success()], + ); + + // insufficient funds in source account via delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &delegate_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &account2_account, &delegate_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &owner_key, + &[], + 900, + ) + .unwrap(), + vec![&account_account, &account2_account, &owner_account], + ), + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, + &delegate_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &account2_account, &delegate_account], + ), + ], + &[Check::err(TokenError::InsufficientFunds.into())], + ); +} + +#[test] +fn test_self_transfer() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let account_key = Pubkey::new_unique(); + let account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account3_key = Pubkey::new_unique(); + let account3_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let delegate_key = Pubkey::new_unique(); + let delegate_account = SolanaAccount::default(); + let owner_key = Pubkey::new_unique(); + let owner_account = SolanaAccount::default(); + let owner2_key = Pubkey::new_unique(); + let owner2_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let rent_sysvar = rent_sysvar(); + + let setup_instructions = vec![ + // create mint + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + // create account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + // create another account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account2_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + // create another account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account3_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + // mint to account + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account_account, &owner_account], + ), + ]; + + // transfer + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&account_account, &account_account, &owner_account], + )], + // no balance change... + &[ + Check::success(), + Check::account(&account_key) + .data_slice(64, &1000u64.to_le_bytes()) + .build(), + ], + ); + + // transfer checked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &account_key, + &owner_key, + &[], + 1000, + 2, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &account_account, + &owner_account, + ], + )], + // no balance change... + &[ + Check::success(), + Check::account(&account_key) + .data_slice(64, &1000u64.to_le_bytes()) + .build(), + ], + ); + + // missing signer + let mut instruction = transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account_key, + &owner_key, + &[], + 1000, + ) + .unwrap(); + instruction.accounts[2].is_signer = false; + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + instruction, + vec![&account_account, &account_account, &owner_account], + )], + &[Check::err(ProgramError::MissingRequiredSignature)], + ); + + // missing signer checked + let mut instruction = transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &account_key, + &owner_key, + &[], + 1000, + 2, + ) + .unwrap(); + instruction.accounts[3].is_signer = false; + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + instruction, + vec![ + &account_account, + &mint_account, + &account_account, + &owner_account, + ], + )], + &[Check::err(ProgramError::MissingRequiredSignature)], + ); + + // missing owner + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account_key, + &owner2_key, + &[], + 1000, + ) + .unwrap(), + vec![&account_account, &account_account, &owner2_account], + )], + &[Check::err(TokenError::OwnerMismatch.into())], + ); + + // missing owner checked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &account_key, + &owner2_key, + &[], + 1000, + 2, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &account_account, + &owner2_account, + ], + )], + &[Check::err(TokenError::OwnerMismatch.into())], + ); + + // insufficient funds + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account_key, + &owner2_key, + &[], + 1001, + ) + .unwrap(), + vec![&account_account, &account_account, &owner_account], + )], + &[Check::err(TokenError::InsufficientFunds.into())], + ); + + // insufficient funds checked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &account_key, + &owner2_key, + &[], + 1001, + 2, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &account_account, + &owner_account, + ], + )], + &[Check::err(TokenError::InsufficientFunds.into())], + ); + + // incorrect decimals + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &account_key, + &owner2_key, + &[], + 1, + 10, // <-- incorrect decimals + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &account_account, + &owner_account, + ], + )], + &[Check::err(TokenError::MintDecimalsMismatch.into())], + ); + + // incorrect mint + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account3_key, // <-- incorrect mint + &account_key, + &owner_key, + &[], + 1, + 2, + ) + .unwrap(), + vec![ + &account_account, + &account3_account, // <-- incorrect mint + &account_account, + &owner_account, + ], + )], + &[Check::err(TokenError::MintMismatch.into())], + ); + + // approve delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + )], + &[Check::success()], + ); + + // delegate transfer + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account_key, + &delegate_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &account_account, &delegate_account], + ), + ], + &[ + Check::success(), + // no balance change... + Check::account(&account_key) + .data_slice(64, &1000u64.to_le_bytes()) + .build(), + Check::account(&account_key) + .data_slice(121, &100u64.to_le_bytes()) + .build(), + ], + ); + + // delegate transfer checked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &account_key, + &delegate_key, + &[], + 100, + 2, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &account_account, + &delegate_account, + ], + ), + ], + &[ + Check::success(), + // no balance change... + Check::account(&account_key) + .data_slice(64, &1000u64.to_le_bytes()) + .build(), + Check::account(&account_key) + .data_slice(121, &100u64.to_le_bytes()) + .build(), + ], + ); + + // delegate insufficient funds + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account_key, + &delegate_key, + &[], + 101, + ) + .unwrap(), + vec![&account_account, &account_account, &delegate_account], + ), + ], + &[Check::err(TokenError::InsufficientFunds.into())], + ); + + // delegate insufficient funds checked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &account_key, + &delegate_key, + &[], + 101, + 2, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &account_account, + &delegate_account, + ], + ), + ], + &[Check::err(TokenError::InsufficientFunds.into())], + ); + + // owner transfer with delegate assigned + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&account_account, &account_account, &owner_account], + ), + ], + &[ + Check::success(), + // no balance change... + Check::account(&account_key) + .data_slice(64, &1000u64.to_le_bytes()) + .build(), + ], + ); + + // owner transfer with delegate assigned checked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + ), + ( + transfer_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &account_key, + &owner_key, + &[], + 1000, + 2, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &account_account, + &owner_account, + ], + ), + ], + &[ + Check::success(), + // no balance change... + Check::account(&account_key) + .data_slice(64, &1000u64.to_le_bytes()) + .build(), + ], + ); +} + +#[test] +fn test_mintable_token_with_zero_supply() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let account_key = Pubkey::new_unique(); + let account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let owner_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let rent_sysvar = rent_sysvar(); + + let decimals = 2; + let setup_instructions = vec![ + // create mint-able token with zero supply + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + decimals, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + // create account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + ]; + + let mut mint_data = [0u8; Mint::LEN]; + Mint { + mint_authority: COption::Some(owner_key), + supply: 0, + decimals, + is_initialized: true, + freeze_authority: COption::None, + } + .pack_into_slice(&mut mint_data); + + // create mint-able token with zero supply + do_process_instructions( + &setup_instructions, + &[ + Check::success(), + Check::account(&mint_key).data(&mint_data).build(), + ], + ); + + // mint to + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account_key, + &owner_key, + &[], + 42, + ) + .unwrap(), + vec![&mint_account, &account_account, &owner_account], + )], + &[ + Check::success(), + Check::account(&account_key) + .data_slice(64, &42u64.to_le_bytes()) + .build(), + ], + ); + + // mint to 2, with incorrect decimals + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account_key, + &owner_key, + &[], + 42, + ) + .unwrap(), + vec![&mint_account, &account_account, &owner_account], + ), + ( + mint_to_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account_key, + &owner_key, + &[], + 42, + decimals + 1, + ) + .unwrap(), + vec![&mint_account, &account_account, &owner_account], + ), + ], + &[ + Check::err(TokenError::MintDecimalsMismatch.into()), + // no balance change... + Check::account(&account_key) + .data_slice(64, &42u64.to_le_bytes()) + .build(), + ], + ); + + // mint to 2 + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account_key, + &owner_key, + &[], + 42, + ) + .unwrap(), + vec![&mint_account, &account_account, &owner_account], + ), + ( + mint_to_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account_key, + &owner_key, + &[], + 42, + decimals, + ) + .unwrap(), + vec![&mint_account, &account_account, &owner_account], + ), + ], + &[ + Check::success(), + Check::account(&account_key) + .data_slice(64, &84u64.to_le_bytes()) + .build(), + ], + ); +} + +#[test] +fn test_approve_dups() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let account1_key = Pubkey::new_unique(); + let account1_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account3_key = Pubkey::new_unique(); + let account3_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let multisig_key = Pubkey::new_unique(); + let multisig_account = SolanaAccount::new( + multisig_minimum_balance(), + Multisig::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let owner_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let rent_sysvar = rent_sysvar(); + + let mut setup_instructions = vec![ + // create mint + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + // create account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + &mint_key, + &account1_key, + ) + .unwrap(), + vec![ + &account1_account, + &mint_account, + &account1_account, + &rent_sysvar, + ], + ), + // create another account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account2_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + // mint to account + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account1_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account1_account, &owner_account], + ), + ]; + + // source-owner approve + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + &account2_key, + &account1_key, + &[], + 500, + ) + .unwrap(), + vec![&account1_account, &account2_account, &account1_account], + )], + &[Check::success()], + ); + + // source-owner approve_checked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + &mint_key, + &account2_key, + &account1_key, + &[], + 500, + 2, + ) + .unwrap(), + vec![ + &account1_account, + &mint_account, + &account2_account, + &account1_account, + ], + )], + &[Check::success()], + ); + + // source-owner revoke + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + &account2_key, + &account1_key, + &[], + 500, + ) + .unwrap(), + vec![&account1_account, &account2_account, &account1_account], + ), + ( + revoke( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + &account1_key, + &[], + ) + .unwrap(), + vec![&account1_account, &account1_account], + ), + ], + &[Check::success()], + ); + + // test source-multisig signer + setup_instructions.extend_from_slice(&[ + ( + initialize_multisig( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &multisig_key, + &[&account3_key], + 1, + ) + .unwrap(), + vec![&multisig_account, &rent_sysvar, &account3_account], + ), + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &mint_key, + &multisig_key, + ) + .unwrap(), + vec![ + &account3_account, + &mint_account, + &multisig_account, + &rent_sysvar, + ], + ), + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account3_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account3_account, &owner_account], + ), + ]); + + do_process_instructions(&setup_instructions, &[Check::success()]); + + // source-multisig-signer approve + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &account2_key, + &multisig_key, + &[&account3_key], + 500, + ) + .unwrap(), + vec![ + &account3_account, + &account2_account, + &multisig_account, + &account3_account, + ], + )], + &[Check::success()], + ); + + // source-multisig-signer approve_checked + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &mint_key, + &account2_key, + &multisig_key, + &[&account3_key], + 500, + 2, + ) + .unwrap(), + vec![ + &account3_account, + &mint_account, + &account2_account, + &multisig_account, + &account3_account, + ], + )], + &[Check::success()], + ); + + // source-owner multisig-signer + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &mint_key, + &account2_key, + &multisig_key, + &[&account3_key], + 500, + 2, + ) + .unwrap(), + vec![ + &account3_account, + &mint_account, + &account2_account, + &multisig_account, + &account3_account, + ], + ), + ( + revoke( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account3_key, + &multisig_key, + &[&account3_key], + ) + .unwrap(), + vec![&account3_account, &multisig_account, &account3_account], + ), + ], + &[Check::success()], + ); +} + +#[test] +fn test_approve() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let account_key = Pubkey::new_unique(); + let account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let delegate_key = Pubkey::new_unique(); + let delegate_account = SolanaAccount::default(); + let owner_key = Pubkey::new_unique(); + let owner_account = SolanaAccount::default(); + let owner2_key = Pubkey::new_unique(); + let owner2_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let rent_sysvar = rent_sysvar(); + + let setup_instructions = vec![ + // create mint + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + // create account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + // create another account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account2_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + ), + // mint to account + ( + mint_to( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &account_key, + &owner_key, + &[], + 1000, + ) + .unwrap(), + vec![&mint_account, &account_account, &owner_account], + ), + ]; + + // missing signer + let mut instruction = approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(); + instruction.accounts[2].is_signer = false; + + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + instruction, + vec![&account_account, &delegate_account, &owner_account], + )], + &[Check::err(ProgramError::MissingRequiredSignature)], + ); + + // no owner + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner2_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner2_account], + )], + &[Check::err(TokenError::OwnerMismatch.into())], + ); + + // approve delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &delegate_key, + &owner_key, + &[], + 100, + ) + .unwrap(), + vec![&account_account, &delegate_account, &owner_account], + )], + &[Check::success()], + ); + + // approve delegate 2, with incorrect decimals + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &delegate_key, + &owner_key, + &[], + 100, + 0, // <-- incorrect decimals + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &delegate_account, + &owner_account, + ], + )], + &[Check::err(TokenError::MintDecimalsMismatch.into())], + ); + + // approve delegate 2, with incorrect mint + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &account2_key, // <-- bad mint + &delegate_key, + &owner_key, + &[], + 100, + 0, + ) + .unwrap(), + vec![ + &account_account, + &account2_account, // <-- bad mint + &delegate_account, + &owner_account, + ], + )], + &[Check::err(TokenError::MintMismatch.into())], + ); + + // approve delegate 2 + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &delegate_key, + &owner_key, + &[], + 100, + 2, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &delegate_account, + &owner_account, + ], + )], + &[Check::success()], + ); + + // revoke delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve_checked( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &delegate_key, + &owner_key, + &[], + 100, + 2, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &delegate_account, + &owner_account, + ], + ), + ( + revoke(&INSTRUCTION_TOKEN_PROGRAM_ID, &account_key, &owner_key, &[]).unwrap(), + vec![&account_account, &owner_account], + ), + ], + &[Check::success()], + ); +} + +#[test] +fn test_set_authority_dups() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let account1_key = Pubkey::new_unique(); + let account1_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let mint_key = Pubkey::new_unique(); + let mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let rent_sysvar = rent_sysvar(); + + let setup_instructions = vec![ + // create mint + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &mint_key, + Some(&mint_key), + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + // create account + ( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + &mint_key, + &account1_key, + ) + .unwrap(), + vec![ + &account1_account, + &mint_account, + &account1_account, + &rent_sysvar, + ], + ), + ]; + + // set mint_authority when currently self + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + Some(&owner_key), + AuthorityType::MintTokens, + &mint_key, + &[], + ) + .unwrap(), + vec![&mint_account, &mint_account], + )], + &[Check::success()], + ); + + // set freeze_authority when currently self + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + Some(&owner_key), + AuthorityType::FreezeAccount, + &mint_key, + &[], + ) + .unwrap(), + vec![&mint_account, &mint_account], + )], + &[Check::success()], + ); + + // set account owner when currently self + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + Some(&owner_key), + AuthorityType::AccountOwner, + &account1_key, + &[], + ) + .unwrap(), + vec![&account1_account, &account1_account], + )], + &[Check::success()], + ); + + // set close_authority when currently self + let mut account = Account::unpack_unchecked(&account1_account.data).unwrap(); + account.state = AccountState::Initialized; + account.mint = mint_key; + account.owner = owner_key; + account.close_authority = COption::Some(account1_key); + let mut close_authority_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &TARGET_TOKEN_PROGRAM_ID, + ); + Account::pack(account, &mut close_authority_account.data).unwrap(); + + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account1_key, + Some(&owner_key), + AuthorityType::CloseAccount, + &account1_key, + &[], + ) + .unwrap(), + vec![&close_authority_account, &close_authority_account], + )], + &[Check::success()], + ); +} + +#[test] +fn test_set_authority() { + let program_id = TARGET_TOKEN_PROGRAM_ID; + let account_key = Pubkey::new_unique(); + let account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let owner_account = SolanaAccount::default(); + let owner2_key = Pubkey::new_unique(); + let owner2_account = SolanaAccount::default(); + let owner3_key = Pubkey::new_unique(); + let owner3_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint2_key = Pubkey::new_unique(); + let mint2_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let rent_sysvar = rent_sysvar(); + + let mut setup_instructions = vec![ + // create new mint with owner + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + &owner_key, + None, + 2, + ) + .unwrap(), + vec![&mint_account, &rent_sysvar], + ), + // create mint with owner and freeze_authority + ( + initialize_mint( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint2_key, + &owner_key, + Some(&owner_key), + 2, + ) + .unwrap(), + vec![&mint2_account, &rent_sysvar], + ), + ]; + + // invalid account + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + Some(&owner2_key), + AuthorityType::AccountOwner, + &owner_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner_account], + )], + &[Check::err(ProgramError::UninitializedAccount)], + ); + + // create account + setup_instructions.push(( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &mint_key, + &owner_key, + ) + .unwrap(), + vec![ + &account_account, + &mint_account, + &owner_account, + &rent_sysvar, + ], + )); + + // create another account + setup_instructions.push(( + initialize_account( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account2_key, + &mint2_key, + &owner_key, + ) + .unwrap(), + vec![ + &account2_account, + &mint2_account, + &owner_account, + &rent_sysvar, + ], + )); + + // missing owner + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + Some(&owner_key), + AuthorityType::AccountOwner, + &owner2_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner2_account], + )], + &[Check::err(TokenError::OwnerMismatch.into())], + ); + + // owner did not sign + let mut instruction = set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + Some(&owner2_key), + AuthorityType::AccountOwner, + &owner_key, + &[], + ) + .unwrap(); + instruction.accounts[1].is_signer = false; + + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[(instruction, vec![&account_account, &owner_account])], + &[Check::err(ProgramError::MissingRequiredSignature)], + ); + + // wrong authority type + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + Some(&owner2_key), + AuthorityType::FreezeAccount, + &owner_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner_account], + )], + &[Check::err(TokenError::AuthorityTypeNotSupported.into())], + ); + + // account owner may not be set to None + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + None, + AuthorityType::AccountOwner, + &owner_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner_account], + )], + &[Check::err(TokenError::InvalidInstruction.into())], + ); + + // set delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &owner2_key, + &owner_key, + &[], + u64::MAX, + ) + .unwrap(), + vec![&account_account, &owner2_account, &owner_account], + )], + &[ + Check::success(), + Check::account(&account_key) + .data_slice(76, owner2_key.as_ref()) // delegate + .build(), + Check::account(&account_key) + .data_slice(121, &u64::MAX.to_le_bytes()) // delegated amount + .build(), + ], + ); + + // set owner + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + Some(&owner3_key), + AuthorityType::AccountOwner, + &owner_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner_account], + )], + &[Check::success()], + ); + + // check delegate cleared + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + approve( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + &owner2_key, + &owner_key, + &[], + u64::MAX, + ) + .unwrap(), + vec![&account_account, &owner2_account, &owner_account], + ), + ( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + Some(&owner3_key), + AuthorityType::AccountOwner, + &owner_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner_account], + ), + ], + &[ + Check::success(), + Check::account(&account_key) + .data_slice(32, owner3_key.as_ref()) // authority + .build(), + Check::account(&account_key) + .data_slice(72, &[0u8; 4]) // delegate option + .build(), + Check::account(&account_key) + .data_slice(121, &0u64.to_le_bytes()) // delegated amount + .build(), + ], + ); + + // set owner without existing delegate + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + Some(&owner3_key), + AuthorityType::AccountOwner, + &owner_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner_account], + ), + ( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + Some(&owner2_key), + AuthorityType::AccountOwner, + &owner3_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner3_account], + ), + ], + &[Check::success()], + ); + + // set close_authority + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + Some(&owner2_key), + AuthorityType::CloseAccount, + &owner_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner2_account], + )], + &[ + Check::success(), + Check::account(&account_key) + .data_slice(129, &[1, 0, 0, 0]) // close authority option + .build(), + Check::account(&account_key) + .data_slice(133, owner2_key.as_ref()) // close authority + .build(), + ], + ); + + // close_authority may be set to None + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + Some(&owner2_key), + AuthorityType::CloseAccount, + &owner_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner2_account], + ), + ( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &account_key, + None, + AuthorityType::CloseAccount, + &owner2_key, + &[], + ) + .unwrap(), + vec![&account_account, &owner2_account], + ), + ], + &[ + Check::success(), + Check::account(&account_key) + .data_slice(129, &[0u8; 4]) // close authority option + .build(), + ], + ); + + // wrong owner + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + Some(&owner3_key), + AuthorityType::MintTokens, + &owner2_key, + &[], + ) + .unwrap(), + vec![&mint_account, &owner2_account], + )], + &[Check::err(TokenError::OwnerMismatch.into())], + ); + + // owner did not sign + let mut instruction = set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + Some(&owner2_key), + AuthorityType::MintTokens, + &owner_key, + &[], + ) + .unwrap(); + instruction.accounts[1].is_signer = false; + + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[(instruction, vec![&mint_account, &owner_account])], + &[Check::err(ProgramError::MissingRequiredSignature)], + ); + + // cannot freeze + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + Some(&owner2_key), + AuthorityType::FreezeAccount, + &owner_key, + &[], + ) + .unwrap(), + vec![&mint_account, &owner_account], + )], + &[Check::err(TokenError::MintCannotFreeze.into())], + ); + + // set owner + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + Some(&owner2_key), + AuthorityType::MintTokens, + &owner_key, + &[], + ) + .unwrap(), + vec![&mint_account, &owner_account], + )], + &[Check::success()], + ); + + // set owner to None + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + None, + AuthorityType::MintTokens, + &owner_key, + &[], + ) + .unwrap(), + vec![&mint_account, &owner_account], + )], + &[Check::success()], + ); + + // test unsetting mint_authority is one-way operation + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + None, + AuthorityType::MintTokens, + &owner_key, + &[], + ) + .unwrap(), + vec![&mint_account, &owner_account], + ), + ( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint_key, + Some(&owner_key), + AuthorityType::MintTokens, + &owner_key, + &[], + ) + .unwrap(), + vec![&mint_account, &owner_account], + ), + ], + &[Check::err(TokenError::FixedSupply.into())], + ); + + // set freeze_authority + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint2_key, + Some(&owner2_key), + AuthorityType::FreezeAccount, + &owner_key, + &[], + ) + .unwrap(), + vec![&mint2_account, &owner_account], + )], + &[Check::success()], + ); + + // test unsetting freeze_authority is one-way operation + do_process_instructions_with_pre_instructions( + Some(&setup_instructions), + &[ + ( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint2_key, + None, + AuthorityType::FreezeAccount, + &owner_key, + &[], + ) + .unwrap(), + vec![&mint2_account, &owner_account], + ), + ( + set_authority( + &INSTRUCTION_TOKEN_PROGRAM_ID, + &mint2_key, + Some(&owner2_key), + AuthorityType::FreezeAccount, + &owner_key, + &[], + ) + .unwrap(), + vec![&mint2_account, &owner_account], + ), + ], + &[Check::err(TokenError::MintCannotFreeze.into())], + ); +} +/* + #[test] + fn test_mint_to_dups() { + let program_id = crate::id(); + let account1_key = Pubkey::new_unique(); + let mut account1_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into(); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into(); + let rent_key = rent::id(); + let mut rent_sysvar = rent_sysvar(); + let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into(); + + // create mint + do_process_instruction_dups( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &mint_key, None, 2).unwrap(), + vec![mint_info.clone(), rent_info.clone()], + ) + .unwrap(); + + // create account + do_process_instruction_dups( + initialize_account(&TOKEN_PROGRAM_ID, &account1_key, &mint_key, &owner_key).unwrap(), + vec![ + account1_info.clone(), + mint_info.clone(), + owner_info.clone(), + rent_info.clone(), + ], + ) + .unwrap(); + + // mint_to when mint_authority is self + do_process_instruction_dups( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account1_key, &mint_key, &[], 42).unwrap(), + vec![mint_info.clone(), account1_info.clone(), mint_info.clone()], + ) + .unwrap(); + + // mint_to_checked when mint_authority is self + do_process_instruction_dups( + mint_to_checked(&TOKEN_PROGRAM_ID, &mint_key, &account1_key, &mint_key, &[], 42, 2).unwrap(), + vec![mint_info.clone(), account1_info.clone(), mint_info.clone()], + ) + .unwrap(); + + // mint_to when mint_authority is account owner + let mut mint = Mint::unpack_unchecked(&mint_info.data.borrow()).unwrap(); + mint.mint_authority = COption::Some(account1_key); + Mint::pack(mint, &mut mint_info.data.borrow_mut()).unwrap(); + do_process_instruction_dups( + mint_to( + &program_id, + &mint_key, + &account1_key, + &account1_key, + &[], + 42, + ) + .unwrap(), + vec![ + mint_info.clone(), + account1_info.clone(), + account1_info.clone(), + ], + ) + .unwrap(); + + // mint_to_checked when mint_authority is account owner + do_process_instruction_dups( + mint_to( + &program_id, + &mint_key, + &account1_key, + &account1_key, + &[], + 42, + ) + .unwrap(), + vec![ + mint_info.clone(), + account1_info.clone(), + account1_info.clone(), + ], + ) + .unwrap(); + } + + #[test] + fn test_mint_to() { + let program_id = crate::id(); + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let mut account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account3_key = Pubkey::new_unique(); + let mut account3_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let mismatch_key = Pubkey::new_unique(); + let mut mismatch_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let owner2_key = Pubkey::new_unique(); + let mut owner2_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint2_key = Pubkey::new_unique(); + let uninitialized_key = Pubkey::new_unique(); + let mut uninitialized_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let mut rent_sysvar = rent_sysvar(); + + // create new mint with owner + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + // create account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // create another account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account2_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account2_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // create another account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account3_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account3_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // create mismatch account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &mismatch_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut mismatch_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap(); + account.mint = mint2_key; + Account::pack(account, &mut mismatch_account.data).unwrap(); + + // mint to + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account_key, &owner_key, &[], 42).unwrap(), + vec![&mut mint_account, &mut account_account, &mut owner_account], + ) + .unwrap(); + + let mint = Mint::unpack_unchecked(&mint_account.data).unwrap(); + assert_eq!(mint.supply, 42); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.amount, 42); + + // mint to another account to test supply accumulation + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(), + vec![&mut mint_account, &mut account2_account, &mut owner_account], + ) + .unwrap(); + + let mint = Mint::unpack_unchecked(&mint_account.data).unwrap(); + assert_eq!(mint.supply, 84); + let account = Account::unpack_unchecked(&account2_account.data).unwrap(); + assert_eq!(account.amount, 42); + + // missing signer + let mut instruction = + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(); + instruction.accounts[2].is_signer = false; + assert_eq!( + Err(ProgramError::MissingRequiredSignature), + do_process_instruction( + instruction, + vec![&mut mint_account, &mut account2_account, &mut owner_account], + ) + ); + + // mismatch account + assert_eq!( + Err(TokenError::MintMismatch.into()), + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &mismatch_key, &owner_key, &[], 42).unwrap(), + vec![&mut mint_account, &mut mismatch_account, &mut owner_account], + ) + ); + + // missing owner + assert_eq!( + Err(TokenError::OwnerMismatch.into()), + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account2_key, &owner2_key, &[], 42).unwrap(), + vec![ + &mut mint_account, + &mut account2_account, + &mut owner2_account, + ], + ) + ); + + // mint not owned by program + let not_program_id = Pubkey::new_unique(); + mint_account.owner = not_program_id; + assert_eq!( + Err(ProgramError::IncorrectProgramId), + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account_key, &owner_key, &[], 0).unwrap(), + vec![&mut mint_account, &mut account_account, &mut owner_account], + ) + ); + mint_account.owner = program_id; + + // account not owned by program + let not_program_id = Pubkey::new_unique(); + account_account.owner = not_program_id; + assert_eq!( + Err(ProgramError::IncorrectProgramId), + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account_key, &owner_key, &[], 0).unwrap(), + vec![&mut mint_account, &mut account_account, &mut owner_account], + ) + ); + account_account.owner = program_id; + + // uninitialized destination account + assert_eq!( + Err(ProgramError::UninitializedAccount), + do_process_instruction( + mint_to( + &program_id, + &mint_key, + &uninitialized_key, + &owner_key, + &[], + 42 + ) + .unwrap(), + vec![ + &mut mint_account, + &mut uninitialized_account, + &mut owner_account, + ], + ) + ); + + // unset mint_authority and test minting fails + do_process_instruction( + set_authority( + &program_id, + &mint_key, + None, + AuthorityType::MintTokens, + &owner_key, + &[], + ) + .unwrap(), + vec![&mut mint_account, &mut owner_account], + ) + .unwrap(); + assert_eq!( + Err(TokenError::FixedSupply.into()), + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account2_key, &owner_key, &[], 42).unwrap(), + vec![&mut mint_account, &mut account2_account, &mut owner_account], + ) + ); + } + + #[test] + fn test_burn_dups() { + let program_id = crate::id(); + let account1_key = Pubkey::new_unique(); + let mut account1_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into(); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let owner_info: AccountInfo = (&owner_key, true, &mut owner_account).into(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into(); + let rent_key = rent::id(); + let mut rent_sysvar = rent_sysvar(); + let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into(); + + // create mint + do_process_instruction_dups( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![mint_info.clone(), rent_info.clone()], + ) + .unwrap(); + + // create account + do_process_instruction_dups( + initialize_account(&TOKEN_PROGRAM_ID, &account1_key, &mint_key, &account1_key).unwrap(), + vec![ + account1_info.clone(), + mint_info.clone(), + account1_info.clone(), + rent_info.clone(), + ], + ) + .unwrap(); + + // mint to account + do_process_instruction_dups( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(), + vec![mint_info.clone(), account1_info.clone(), owner_info.clone()], + ) + .unwrap(); + + // source-owner burn + do_process_instruction_dups( + burn( + &program_id, + &mint_key, + &account1_key, + &account1_key, + &[], + 500, + ) + .unwrap(), + vec![ + account1_info.clone(), + mint_info.clone(), + account1_info.clone(), + ], + ) + .unwrap(); + + // source-owner burn_checked + do_process_instruction_dups( + burn_checked( + &program_id, + &account1_key, + &mint_key, + &account1_key, + &[], + 500, + 2, + ) + .unwrap(), + vec![ + account1_info.clone(), + mint_info.clone(), + account1_info.clone(), + ], + ) + .unwrap(); + + // mint-owner burn + do_process_instruction_dups( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(), + vec![mint_info.clone(), account1_info.clone(), owner_info.clone()], + ) + .unwrap(); + let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap(); + account.owner = mint_key; + Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap(); + do_process_instruction_dups( + burn(&TOKEN_PROGRAM_ID, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(), + vec![account1_info.clone(), mint_info.clone(), mint_info.clone()], + ) + .unwrap(); + + // mint-owner burn_checked + do_process_instruction_dups( + burn_checked( + &program_id, + &account1_key, + &mint_key, + &mint_key, + &[], + 500, + 2, + ) + .unwrap(), + vec![account1_info.clone(), mint_info.clone(), mint_info.clone()], + ) + .unwrap(); + + // source-delegate burn + do_process_instruction_dups( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(), + vec![mint_info.clone(), account1_info.clone(), owner_info.clone()], + ) + .unwrap(); + let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap(); + account.delegated_amount = 1000; + account.delegate = COption::Some(account1_key); + account.owner = owner_key; + Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap(); + do_process_instruction_dups( + burn( + &program_id, + &account1_key, + &mint_key, + &account1_key, + &[], + 500, + ) + .unwrap(), + vec![ + account1_info.clone(), + mint_info.clone(), + account1_info.clone(), + ], + ) + .unwrap(); + + // source-delegate burn_checked + do_process_instruction_dups( + burn_checked( + &program_id, + &account1_key, + &mint_key, + &account1_key, + &[], + 500, + 2, + ) + .unwrap(), + vec![ + account1_info.clone(), + mint_info.clone(), + account1_info.clone(), + ], + ) + .unwrap(); + + // mint-delegate burn + do_process_instruction_dups( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account1_key, &owner_key, &[], 1000).unwrap(), + vec![mint_info.clone(), account1_info.clone(), owner_info.clone()], + ) + .unwrap(); + let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap(); + account.delegated_amount = 1000; + account.delegate = COption::Some(mint_key); + account.owner = owner_key; + Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap(); + do_process_instruction_dups( + burn(&TOKEN_PROGRAM_ID, &account1_key, &mint_key, &mint_key, &[], 500).unwrap(), + vec![account1_info.clone(), mint_info.clone(), mint_info.clone()], + ) + .unwrap(); + + // mint-delegate burn_checked + do_process_instruction_dups( + burn_checked( + &program_id, + &account1_key, + &mint_key, + &mint_key, + &[], + 500, + 2, + ) + .unwrap(), + vec![account1_info.clone(), mint_info.clone(), mint_info.clone()], + ) + .unwrap(); + } + + #[test] + fn test_burn() { + let program_id = crate::id(); + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let mut account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account3_key = Pubkey::new_unique(); + let mut account3_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let delegate_key = Pubkey::new_unique(); + let mut delegate_account = SolanaAccount::default(); + let mismatch_key = Pubkey::new_unique(); + let mut mismatch_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let owner2_key = Pubkey::new_unique(); + let mut owner2_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint2_key = Pubkey::new_unique(); + let mut rent_sysvar = rent_sysvar(); + + // create new mint + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + // create account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // create another account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account2_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account2_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // create another account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account3_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account3_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // create mismatch account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &mismatch_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut mismatch_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // mint to account + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(), + vec![&mut mint_account, &mut account_account, &mut owner_account], + ) + .unwrap(); + + // mint to mismatch account and change mint key + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &mismatch_key, &owner_key, &[], 1000).unwrap(), + vec![&mut mint_account, &mut mismatch_account, &mut owner_account], + ) + .unwrap(); + let mut account = Account::unpack_unchecked(&mismatch_account.data).unwrap(); + account.mint = mint2_key; + Account::pack(account, &mut mismatch_account.data).unwrap(); + + // missing signer + let mut instruction = + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &delegate_key, &[], 42).unwrap(); + instruction.accounts[1].is_signer = false; + assert_eq!( + Err(TokenError::OwnerMismatch.into()), + do_process_instruction( + instruction, + vec![ + &mut account_account, + &mut mint_account, + &mut delegate_account + ], + ) + ); + + // missing owner + assert_eq!( + Err(TokenError::OwnerMismatch.into()), + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner2_key, &[], 42).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner2_account], + ) + ); + + // account not owned by program + let not_program_id = Pubkey::new_unique(); + account_account.owner = not_program_id; + assert_eq!( + Err(ProgramError::IncorrectProgramId), + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[], 0).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + ); + account_account.owner = program_id; + + // mint not owned by program + let not_program_id = Pubkey::new_unique(); + mint_account.owner = not_program_id; + assert_eq!( + Err(ProgramError::IncorrectProgramId), + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[], 0).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + ); + mint_account.owner = program_id; + + // mint mismatch + assert_eq!( + Err(TokenError::MintMismatch.into()), + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &mismatch_key, &mint_key, &owner_key, &[], 42).unwrap(), + vec![&mut mismatch_account, &mut mint_account, &mut owner_account], + ) + ); + + // burn + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[], 21).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + .unwrap(); + + // burn_checked, with incorrect decimals + assert_eq!( + Err(TokenError::MintDecimalsMismatch.into()), + do_process_instruction( + burn_checked(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[], 21, 3).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + ); + + // burn_checked + do_process_instruction( + burn_checked(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[], 21, 2).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + .unwrap(); + + let mint = Mint::unpack_unchecked(&mint_account.data).unwrap(); + assert_eq!(mint.supply, 2000 - 42); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.amount, 1000 - 42); + + // insufficient funds + assert_eq!( + Err(TokenError::InsufficientFunds.into()), + do_process_instruction( + burn( + &program_id, + &account_key, + &mint_key, + &owner_key, + &[], + 100_000_000 + ) + .unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + ); + + // approve delegate + do_process_instruction( + approve( + &program_id, + &account_key, + &delegate_key, + &owner_key, + &[], + 84, + ) + .unwrap(), + vec![ + &mut account_account, + &mut delegate_account, + &mut owner_account, + ], + ) + .unwrap(); + + // not a delegate of source account + assert_eq!( + Err(TokenError::OwnerMismatch.into()), + do_process_instruction( + burn( + &program_id, + &account_key, + &mint_key, + &owner2_key, // <-- incorrect owner or delegate + &[], + 1, + ) + .unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner2_account], + ) + ); + + // insufficient funds approved via delegate + assert_eq!( + Err(TokenError::InsufficientFunds.into()), + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &delegate_key, &[], 85).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut delegate_account + ], + ) + ); + + // burn via delegate + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &delegate_key, &[], 84).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut delegate_account, + ], + ) + .unwrap(); + + // match + let mint = Mint::unpack_unchecked(&mint_account.data).unwrap(); + assert_eq!(mint.supply, 2000 - 42 - 84); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.amount, 1000 - 42 - 84); + + // insufficient funds approved via delegate + assert_eq!( + Err(TokenError::OwnerMismatch.into()), + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &delegate_key, &[], 1).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut delegate_account + ], + ) + ); + } + + #[test] + fn test_burn_and_close_system_and_incinerator_tokens() { + let program_id = crate::id(); + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let incinerator_account_key = Pubkey::new_unique(); + let mut incinerator_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let system_account_key = Pubkey::new_unique(); + let mut system_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let recipient_key = Pubkey::new_unique(); + let mut recipient_account = SolanaAccount::default(); + let mut mock_incinerator_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + + // create new mint + do_process_instruction( + initialize_mint2(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + // create account + do_process_instruction( + initialize_account3(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![&mut account_account, &mut mint_account], + ) + .unwrap(); + + // create incinerator- and system-owned accounts + do_process_instruction( + initialize_account3( + &program_id, + &incinerator_account_key, + &mint_key, + &solana_program::incinerator::id(), + ) + .unwrap(), + vec![&mut incinerator_account, &mut mint_account], + ) + .unwrap(); + do_process_instruction( + initialize_account3( + &program_id, + &system_account_key, + &mint_key, + &solana_program::system_program::id(), + ) + .unwrap(), + vec![&mut system_account, &mut mint_account], + ) + .unwrap(); + + // mint to account + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(), + vec![&mut mint_account, &mut account_account, &mut owner_account], + ) + .unwrap(); + + // transfer half to incinerator, half to system program + do_process_instruction( + transfer( + &program_id, + &account_key, + &incinerator_account_key, + &owner_key, + &[], + 500, + ) + .unwrap(), + vec![ + &mut account_account, + &mut incinerator_account, + &mut owner_account, + ], + ) + .unwrap(); + do_process_instruction( + transfer( + &program_id, + &account_key, + &system_account_key, + &owner_key, + &[], + 500, + ) + .unwrap(), + vec![ + &mut account_account, + &mut system_account, + &mut owner_account, + ], + ) + .unwrap(); + + // close with balance fails + assert_eq!( + Err(TokenError::NonNativeHasBalance.into()), + do_process_instruction( + close_account( + &program_id, + &incinerator_account_key, + &solana_program::incinerator::id(), + &owner_key, + &[] + ) + .unwrap(), + vec![ + &mut incinerator_account, + &mut mock_incinerator_account, + &mut owner_account, + ], + ) + ); + assert_eq!( + Err(TokenError::NonNativeHasBalance.into()), + do_process_instruction( + close_account( + &program_id, + &system_account_key, + &solana_program::incinerator::id(), + &owner_key, + &[] + ) + .unwrap(), + vec![ + &mut system_account, + &mut mock_incinerator_account, + &mut owner_account, + ], + ) + ); + + // anyone can burn + do_process_instruction( + burn( + &program_id, + &incinerator_account_key, + &mint_key, + &recipient_key, + &[], + 500, + ) + .unwrap(), + vec![ + &mut incinerator_account, + &mut mint_account, + &mut recipient_account, + ], + ) + .unwrap(); + do_process_instruction( + burn( + &program_id, + &system_account_key, + &mint_key, + &recipient_key, + &[], + 500, + ) + .unwrap(), + vec![ + &mut system_account, + &mut mint_account, + &mut recipient_account, + ], + ) + .unwrap(); + + // closing fails if destination is not the incinerator + assert_eq!( + Err(ProgramError::InvalidAccountData), + do_process_instruction( + close_account( + &program_id, + &incinerator_account_key, + &recipient_key, + &owner_key, + &[] + ) + .unwrap(), + vec![ + &mut incinerator_account, + &mut recipient_account, + &mut owner_account, + ], + ) + ); + assert_eq!( + Err(ProgramError::InvalidAccountData), + do_process_instruction( + close_account( + &program_id, + &system_account_key, + &recipient_key, + &owner_key, + &[] + ) + .unwrap(), + vec![ + &mut system_account, + &mut recipient_account, + &mut owner_account, + ], + ) + ); + + // closing succeeds with incinerator recipient + do_process_instruction( + close_account( + &program_id, + &incinerator_account_key, + &solana_program::incinerator::id(), + &owner_key, + &[], + ) + .unwrap(), + vec![ + &mut incinerator_account, + &mut mock_incinerator_account, + &mut owner_account, + ], + ) + .unwrap(); + + do_process_instruction( + close_account( + &program_id, + &system_account_key, + &solana_program::incinerator::id(), + &owner_key, + &[], + ) + .unwrap(), + vec![ + &mut system_account, + &mut mock_incinerator_account, + &mut owner_account, + ], + ) + .unwrap(); + } + + #[test] + fn test_multisig() { + let program_id = crate::id(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let account_key = Pubkey::new_unique(); + let mut account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let mut account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let multisig_key = Pubkey::new_unique(); + let mut multisig_account = SolanaAccount::new(42, Multisig::get_packed_len(), &program_id); + let multisig_delegate_key = Pubkey::new_unique(); + let mut multisig_delegate_account = SolanaAccount::new( + multisig_minimum_balance(), + Multisig::get_packed_len(), + &program_id, + ); + let signer_keys = vec![Pubkey::new_unique(); MAX_SIGNERS]; + let signer_key_refs: Vec<&Pubkey> = signer_keys.iter().collect(); + let mut signer_accounts = vec![SolanaAccount::new(0, 0, &program_id); MAX_SIGNERS]; + let mut rent_sysvar = rent_sysvar(); + + // multisig is not rent exempt + let account_info_iter = &mut signer_accounts.iter_mut(); + assert_eq!( + Err(TokenError::NotRentExempt.into()), + do_process_instruction( + initialize_multisig(&TOKEN_PROGRAM_ID, &multisig_key, &[&signer_keys[0]], 1).unwrap(), + vec![ + &mut multisig_account, + &mut rent_sysvar, + account_info_iter.next().unwrap(), + ], + ) + ); + + multisig_account.lamports = multisig_minimum_balance(); + let mut multisig_account2 = multisig_account.clone(); + + // single signer + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + initialize_multisig(&TOKEN_PROGRAM_ID, &multisig_key, &[&signer_keys[0]], 1).unwrap(), + vec![ + &mut multisig_account, + &mut rent_sysvar, + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // single signer using `initialize_multisig2` + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + initialize_multisig2(&TOKEN_PROGRAM_ID, &multisig_key, &[&signer_keys[0]], 1).unwrap(), + vec![&mut multisig_account2, account_info_iter.next().unwrap()], + ) + .unwrap(); + + // multiple signer + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + initialize_multisig( + &program_id, + &multisig_delegate_key, + &signer_key_refs, + MAX_SIGNERS as u8, + ) + .unwrap(), + vec![ + &mut multisig_delegate_account, + &mut rent_sysvar, + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // create new mint with multisig owner + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &multisig_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + // create account with multisig owner + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &multisig_key).unwrap(), + vec![ + &mut account, + &mut mint_account, + &mut multisig_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // create another account with multisig owner + do_process_instruction( + initialize_account( + &program_id, + &account2_key, + &mint_key, + &multisig_delegate_key, + ) + .unwrap(), + vec![ + &mut account2_account, + &mut mint_account, + &mut multisig_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // mint to account + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + mint_to( + &program_id, + &mint_key, + &account_key, + &multisig_key, + &[&signer_keys[0]], + 1000, + ) + .unwrap(), + vec![ + &mut mint_account, + &mut account, + &mut multisig_account, + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // approve + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + approve( + &program_id, + &account_key, + &multisig_delegate_key, + &multisig_key, + &[&signer_keys[0]], + 100, + ) + .unwrap(), + vec![ + &mut account, + &mut multisig_delegate_account, + &mut multisig_account, + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // transfer + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + transfer( + &program_id, + &account_key, + &account2_key, + &multisig_key, + &[&signer_keys[0]], + 42, + ) + .unwrap(), + vec![ + &mut account, + &mut account2_account, + &mut multisig_account, + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // transfer via delegate + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + transfer( + &program_id, + &account_key, + &account2_key, + &multisig_delegate_key, + &signer_key_refs, + 42, + ) + .unwrap(), + vec![ + &mut account, + &mut account2_account, + &mut multisig_delegate_account, + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // mint to + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + mint_to( + &program_id, + &mint_key, + &account2_key, + &multisig_key, + &[&signer_keys[0]], + 42, + ) + .unwrap(), + vec![ + &mut mint_account, + &mut account2_account, + &mut multisig_account, + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // burn + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + burn( + &program_id, + &account_key, + &mint_key, + &multisig_key, + &[&signer_keys[0]], + 42, + ) + .unwrap(), + vec![ + &mut account, + &mut mint_account, + &mut multisig_account, + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // burn via delegate + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + burn( + &program_id, + &account_key, + &mint_key, + &multisig_delegate_key, + &signer_key_refs, + 42, + ) + .unwrap(), + vec![ + &mut account, + &mut mint_account, + &mut multisig_delegate_account, + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // freeze account + let account3_key = Pubkey::new_unique(); + let mut account3_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let mint2_key = Pubkey::new_unique(); + let mut mint2_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + do_process_instruction( + initialize_mint( + &program_id, + &mint2_key, + &multisig_key, + Some(&multisig_key), + 2, + ) + .unwrap(), + vec![&mut mint2_account, &mut rent_sysvar], + ) + .unwrap(); + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account3_key, &mint2_key, &owner_key).unwrap(), + vec![ + &mut account3_account, + &mut mint2_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + mint_to( + &program_id, + &mint2_key, + &account3_key, + &multisig_key, + &[&signer_keys[0]], + 1000, + ) + .unwrap(), + vec![ + &mut mint2_account, + &mut account3_account, + &mut multisig_account, + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + freeze_account( + &program_id, + &account3_key, + &mint2_key, + &multisig_key, + &[&signer_keys[0]], + ) + .unwrap(), + vec![ + &mut account3_account, + &mut mint2_account, + &mut multisig_account, + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // do SetAuthority on mint + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + set_authority( + &program_id, + &mint_key, + Some(&owner_key), + AuthorityType::MintTokens, + &multisig_key, + &[&signer_keys[0]], + ) + .unwrap(), + vec![ + &mut mint_account, + &mut multisig_account, + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + + // do SetAuthority on account + let account_info_iter = &mut signer_accounts.iter_mut(); + do_process_instruction( + set_authority( + &program_id, + &account_key, + Some(&owner_key), + AuthorityType::AccountOwner, + &multisig_key, + &[&signer_keys[0]], + ) + .unwrap(), + vec![ + &mut account, + &mut multisig_account, + account_info_iter.next().unwrap(), + ], + ) + .unwrap(); + } + + #[test] + fn test_validate_owner() { + let program_id = crate::id(); + let owner_key = Pubkey::new_unique(); + let mut signer_keys = [Pubkey::default(); MAX_SIGNERS]; + for signer_key in signer_keys.iter_mut().take(MAX_SIGNERS) { + *signer_key = Pubkey::new_unique(); + } + let mut signer_lamports = 0; + let mut signer_data = vec![]; + let mut signers = vec![ + AccountInfo::new( + &owner_key, + true, + false, + &mut signer_lamports, + &mut signer_data, + &program_id, + false, + Epoch::default(), + ); + MAX_SIGNERS + 1 + ]; + for (signer, key) in signers.iter_mut().zip(&signer_keys) { + signer.key = key; + } + let mut lamports = 0; + let mut data = vec![0; Multisig::get_packed_len()]; + let mut multisig = Multisig::unpack_unchecked(&data).unwrap(); + multisig.m = MAX_SIGNERS as u8; + multisig.n = MAX_SIGNERS as u8; + multisig.signers = signer_keys; + multisig.is_initialized = true; + Multisig::pack(multisig, &mut data).unwrap(); + let owner_account_info = AccountInfo::new( + &owner_key, + false, + false, + &mut lamports, + &mut data, + &program_id, + false, + Epoch::default(), + ); + + // full 11 of 11 + Processor::validate_owner(&TOKEN_PROGRAM_ID, &owner_key, &owner_account_info, &signers).unwrap(); + + // 1 of 11 + { + let mut multisig = + Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap(); + multisig.m = 1; + Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap(); + } + Processor::validate_owner(&TOKEN_PROGRAM_ID, &owner_key, &owner_account_info, &signers).unwrap(); + + // 2:1 + { + let mut multisig = + Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap(); + multisig.m = 2; + multisig.n = 1; + Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap(); + } + assert_eq!( + Err(ProgramError::MissingRequiredSignature), + Processor::validate_owner(&TOKEN_PROGRAM_ID, &owner_key, &owner_account_info, &signers) + ); + + // 0:11 + { + let mut multisig = + Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap(); + multisig.m = 0; + multisig.n = 11; + Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap(); + } + Processor::validate_owner(&TOKEN_PROGRAM_ID, &owner_key, &owner_account_info, &signers).unwrap(); + + // 2:11 but 0 provided + { + let mut multisig = + Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap(); + multisig.m = 2; + multisig.n = 11; + Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap(); + } + assert_eq!( + Err(ProgramError::MissingRequiredSignature), + Processor::validate_owner(&TOKEN_PROGRAM_ID, &owner_key, &owner_account_info, &[]) + ); + // 2:11 but 1 provided + { + let mut multisig = + Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap(); + multisig.m = 2; + multisig.n = 11; + Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap(); + } + assert_eq!( + Err(ProgramError::MissingRequiredSignature), + Processor::validate_owner(&TOKEN_PROGRAM_ID, &owner_key, &owner_account_info, &signers[0..1]) + ); + + // 2:11, 2 from middle provided + { + let mut multisig = + Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap(); + multisig.m = 2; + multisig.n = 11; + Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap(); + } + Processor::validate_owner(&TOKEN_PROGRAM_ID, &owner_key, &owner_account_info, &signers[5..7]) + .unwrap(); + + // 11:11, one is not a signer + { + let mut multisig = + Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap(); + multisig.m = 11; + multisig.n = 11; + Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap(); + } + signers[5].is_signer = false; + assert_eq!( + Err(ProgramError::MissingRequiredSignature), + Processor::validate_owner(&TOKEN_PROGRAM_ID, &owner_key, &owner_account_info, &signers) + ); + signers[5].is_signer = true; + + // 11:11, single signer signs multiple times + { + let mut signer_lamports = 0; + let mut signer_data = vec![]; + let signers = vec![ + AccountInfo::new( + &signer_keys[5], + true, + false, + &mut signer_lamports, + &mut signer_data, + &program_id, + false, + Epoch::default(), + ); + MAX_SIGNERS + 1 + ]; + let mut multisig = + Multisig::unpack_unchecked(&owner_account_info.data.borrow()).unwrap(); + multisig.m = 11; + multisig.n = 11; + Multisig::pack(multisig, &mut owner_account_info.data.borrow_mut()).unwrap(); + assert_eq!( + Err(ProgramError::MissingRequiredSignature), + Processor::validate_owner(&TOKEN_PROGRAM_ID, &owner_key, &owner_account_info, &signers) + ); + } + } + + #[test] + fn test_owner_close_account_dups() { + let program_id = crate::id(); + let owner_key = Pubkey::new_unique(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into(); + let rent_key = rent::id(); + let mut rent_sysvar = rent_sysvar(); + let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into(); + + // create mint + do_process_instruction_dups( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![mint_info.clone(), rent_info.clone()], + ) + .unwrap(); + + let to_close_key = Pubkey::new_unique(); + let mut to_close_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let to_close_account_info: AccountInfo = + (&to_close_key, true, &mut to_close_account).into(); + let destination_account_key = Pubkey::new_unique(); + let mut destination_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let destination_account_info: AccountInfo = + (&destination_account_key, true, &mut destination_account).into(); + // create account + do_process_instruction_dups( + initialize_account(&TOKEN_PROGRAM_ID, &to_close_key, &mint_key, &to_close_key).unwrap(), + vec![ + to_close_account_info.clone(), + mint_info.clone(), + to_close_account_info.clone(), + rent_info.clone(), + ], + ) + .unwrap(); + + // source-owner close + do_process_instruction_dups( + close_account( + &program_id, + &to_close_key, + &destination_account_key, + &to_close_key, + &[], + ) + .unwrap(), + vec![ + to_close_account_info.clone(), + destination_account_info.clone(), + to_close_account_info.clone(), + ], + ) + .unwrap(); + assert_eq!(*to_close_account_info.data.borrow(), &[0u8; Account::LEN]); + } + + #[test] + fn test_close_authority_close_account_dups() { + let program_id = crate::id(); + let owner_key = Pubkey::new_unique(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint_info: AccountInfo = (&mint_key, false, &mut mint_account).into(); + let rent_key = rent::id(); + let mut rent_sysvar = rent_sysvar(); + let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into(); + + // create mint + do_process_instruction_dups( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![mint_info.clone(), rent_info.clone()], + ) + .unwrap(); + + let to_close_key = Pubkey::new_unique(); + let mut to_close_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let to_close_account_info: AccountInfo = + (&to_close_key, true, &mut to_close_account).into(); + let destination_account_key = Pubkey::new_unique(); + let mut destination_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let destination_account_info: AccountInfo = + (&destination_account_key, true, &mut destination_account).into(); + // create account + do_process_instruction_dups( + initialize_account(&TOKEN_PROGRAM_ID, &to_close_key, &mint_key, &to_close_key).unwrap(), + vec![ + to_close_account_info.clone(), + mint_info.clone(), + to_close_account_info.clone(), + rent_info.clone(), + ], + ) + .unwrap(); + let mut account = Account::unpack_unchecked(&to_close_account_info.data.borrow()).unwrap(); + account.close_authority = COption::Some(to_close_key); + account.owner = owner_key; + Account::pack(account, &mut to_close_account_info.data.borrow_mut()).unwrap(); + do_process_instruction_dups( + close_account( + &program_id, + &to_close_key, + &destination_account_key, + &to_close_key, + &[], + ) + .unwrap(), + vec![ + to_close_account_info.clone(), + destination_account_info.clone(), + to_close_account_info.clone(), + ], + ) + .unwrap(); + assert_eq!(*to_close_account_info.data.borrow(), &[0u8; Account::LEN]); + } + + #[test] + fn test_close_account() { + let program_id = crate::id(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let mut account2_account = SolanaAccount::new( + account_minimum_balance() + 42, + Account::get_packed_len(), + &program_id, + ); + let account3_key = Pubkey::new_unique(); + let mut account3_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let owner2_key = Pubkey::new_unique(); + let mut owner2_account = SolanaAccount::default(); + let mut rent_sysvar = rent_sysvar(); + + // uninitialized + assert_eq!( + Err(ProgramError::UninitializedAccount), + do_process_instruction( + close_account(&TOKEN_PROGRAM_ID, &account_key, &account3_key, &owner2_key, &[]).unwrap(), + vec![ + &mut account_account, + &mut account3_account, + &mut owner2_account, + ], + ) + ); + + // initialize and mint to non-native account + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account_key, &owner_key, &[], 42).unwrap(), + vec![ + &mut mint_account, + &mut account_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.amount, 42); + + // initialize native account + do_process_instruction( + initialize_account( + &program_id, + &account2_key, + &crate::native_mint::id(), + &owner_key, + ) + .unwrap(), + vec![ + &mut account2_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + let account = Account::unpack_unchecked(&account2_account.data).unwrap(); + assert!(account.is_native()); + assert_eq!(account.amount, 42); + + // close non-native account with balance + assert_eq!( + Err(TokenError::NonNativeHasBalance.into()), + do_process_instruction( + close_account(&TOKEN_PROGRAM_ID, &account_key, &account3_key, &owner_key, &[]).unwrap(), + vec![ + &mut account_account, + &mut account3_account, + &mut owner_account, + ], + ) + ); + assert_eq!(account_account.lamports, account_minimum_balance()); + + // empty account + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[], 42).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + .unwrap(); + + // wrong owner + assert_eq!( + Err(TokenError::OwnerMismatch.into()), + do_process_instruction( + close_account(&TOKEN_PROGRAM_ID, &account_key, &account3_key, &owner2_key, &[]).unwrap(), + vec![ + &mut account_account, + &mut account3_account, + &mut owner2_account, + ], + ) + ); + + // close account + do_process_instruction( + close_account(&TOKEN_PROGRAM_ID, &account_key, &account3_key, &owner_key, &[]).unwrap(), + vec![ + &mut account_account, + &mut account3_account, + &mut owner_account, + ], + ) + .unwrap(); + assert_eq!(account_account.lamports, 0); + assert_eq!(account3_account.lamports, 2 * account_minimum_balance()); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.amount, 0); + + // fund and initialize new non-native account to test close authority + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner2_key = Pubkey::new_unique(); + let mut owner2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + account_account.lamports = 2; + + do_process_instruction( + set_authority( + &program_id, + &account_key, + Some(&owner2_key), + AuthorityType::CloseAccount, + &owner_key, + &[], + ) + .unwrap(), + vec![&mut account_account, &mut owner_account], + ) + .unwrap(); + + // account owner cannot authorize close if close_authority is set + assert_eq!( + Err(TokenError::OwnerMismatch.into()), + do_process_instruction( + close_account(&TOKEN_PROGRAM_ID, &account_key, &account3_key, &owner_key, &[]).unwrap(), + vec![ + &mut account_account, + &mut account3_account, + &mut owner_account, + ], + ) + ); + + // close non-native account with close_authority + do_process_instruction( + close_account(&TOKEN_PROGRAM_ID, &account_key, &account3_key, &owner2_key, &[]).unwrap(), + vec![ + &mut account_account, + &mut account3_account, + &mut owner2_account, + ], + ) + .unwrap(); + assert_eq!(account_account.lamports, 0); + assert_eq!(account3_account.lamports, 2 * account_minimum_balance() + 2); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.amount, 0); + + // close native account + do_process_instruction( + close_account(&TOKEN_PROGRAM_ID, &account2_key, &account3_key, &owner_key, &[]).unwrap(), + vec![ + &mut account2_account, + &mut account3_account, + &mut owner_account, + ], + ) + .unwrap(); + assert_eq!(account2_account.data, [0u8; Account::LEN]); + assert_eq!( + account3_account.lamports, + 3 * account_minimum_balance() + 2 + 42 + ); + } + + #[test] + fn test_native_token() { + let program_id = crate::id(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance() + 40, + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let mut account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account3_key = Pubkey::new_unique(); + let mut account3_account = SolanaAccount::new(account_minimum_balance(), 0, &program_id); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let owner2_key = Pubkey::new_unique(); + let mut owner2_account = SolanaAccount::default(); + let owner3_key = Pubkey::new_unique(); + let mut rent_sysvar = rent_sysvar(); + + // initialize native account + do_process_instruction( + initialize_account( + &program_id, + &account_key, + &crate::native_mint::id(), + &owner_key, + ) + .unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert!(account.is_native()); + assert_eq!(account.amount, 40); + + // initialize native account + do_process_instruction( + initialize_account( + &program_id, + &account2_key, + &crate::native_mint::id(), + &owner_key, + ) + .unwrap(), + vec![ + &mut account2_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + let account = Account::unpack_unchecked(&account2_account.data).unwrap(); + assert!(account.is_native()); + assert_eq!(account.amount, 0); + + // mint_to unsupported + assert_eq!( + Err(TokenError::NativeNotSupported.into()), + do_process_instruction( + mint_to( + &program_id, + &crate::native_mint::id(), + &account_key, + &owner_key, + &[], + 42 + ) + .unwrap(), + vec![&mut mint_account, &mut account_account, &mut owner_account], + ) + ); + + // burn unsupported + let bogus_mint_key = Pubkey::new_unique(); + let mut bogus_mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &bogus_mint_key, &owner_key, None, 2).unwrap(), + vec![&mut bogus_mint_account, &mut rent_sysvar], + ) + .unwrap(); + + assert_eq!( + Err(TokenError::NativeNotSupported.into()), + do_process_instruction( + burn( + &program_id, + &account_key, + &bogus_mint_key, + &owner_key, + &[], + 42 + ) + .unwrap(), + vec![ + &mut account_account, + &mut bogus_mint_account, + &mut owner_account + ], + ) + ); + + // ensure can't transfer below rent-exempt reserve + assert_eq!( + Err(TokenError::InsufficientFunds.into()), + do_process_instruction( + transfer( + &program_id, + &account_key, + &account2_key, + &owner_key, + &[], + 50, + ) + .unwrap(), + vec![ + &mut account_account, + &mut account2_account, + &mut owner_account, + ], + ) + ); + + // transfer between native accounts + do_process_instruction( + transfer( + &program_id, + &account_key, + &account2_key, + &owner_key, + &[], + 40, + ) + .unwrap(), + vec![ + &mut account_account, + &mut account2_account, + &mut owner_account, + ], + ) + .unwrap(); + assert_eq!(account_account.lamports, account_minimum_balance()); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert!(account.is_native()); + assert_eq!(account.amount, 0); + assert_eq!(account2_account.lamports, account_minimum_balance() + 40); + let account = Account::unpack_unchecked(&account2_account.data).unwrap(); + assert!(account.is_native()); + assert_eq!(account.amount, 40); + + // set close authority + do_process_instruction( + set_authority( + &program_id, + &account_key, + Some(&owner3_key), + AuthorityType::CloseAccount, + &owner_key, + &[], + ) + .unwrap(), + vec![&mut account_account, &mut owner_account], + ) + .unwrap(); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.close_authority, COption::Some(owner3_key)); + + // set new account owner + do_process_instruction( + set_authority( + &program_id, + &account_key, + Some(&owner2_key), + AuthorityType::AccountOwner, + &owner_key, + &[], + ) + .unwrap(), + vec![&mut account_account, &mut owner_account], + ) + .unwrap(); + + // close authority cleared + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.close_authority, COption::None); + + // close native account + do_process_instruction( + close_account(&TOKEN_PROGRAM_ID, &account_key, &account3_key, &owner2_key, &[]).unwrap(), + vec![ + &mut account_account, + &mut account3_account, + &mut owner2_account, + ], + ) + .unwrap(); + assert_eq!(account_account.lamports, 0); + assert_eq!(account3_account.lamports, 2 * account_minimum_balance()); + assert_eq!(account_account.data, [0u8; Account::LEN]); + } + + #[test] + fn test_overflow() { + let program_id = crate::id(); + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let mut account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let owner2_key = Pubkey::new_unique(); + let mut owner2_account = SolanaAccount::default(); + let mint_owner_key = Pubkey::new_unique(); + let mut mint_owner_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mut rent_sysvar = rent_sysvar(); + + // create new mint with owner + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &mint_owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + // create an account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // create another account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account2_key, &mint_key, &owner2_key).unwrap(), + vec![ + &mut account2_account, + &mut mint_account, + &mut owner2_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // mint the max to an account + do_process_instruction( + mint_to( + &program_id, + &mint_key, + &account_key, + &mint_owner_key, + &[], + u64::MAX, + ) + .unwrap(), + vec![ + &mut mint_account, + &mut account_account, + &mut mint_owner_account, + ], + ) + .unwrap(); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.amount, u64::MAX); + + // attempt to mint one more to account + assert_eq!( + Err(TokenError::Overflow.into()), + do_process_instruction( + mint_to( + &program_id, + &mint_key, + &account_key, + &mint_owner_key, + &[], + 1, + ) + .unwrap(), + vec![ + &mut mint_account, + &mut account_account, + &mut mint_owner_account, + ], + ) + ); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.amount, u64::MAX); + + // attempt to mint one more to the other account + assert_eq!( + Err(TokenError::Overflow.into()), + do_process_instruction( + mint_to( + &program_id, + &mint_key, + &account2_key, + &mint_owner_key, + &[], + 1, + ) + .unwrap(), + vec![ + &mut mint_account, + &mut account2_account, + &mut mint_owner_account, + ], + ) + ); + + // burn some of the supply + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[], 100).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + .unwrap(); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.amount, u64::MAX - 100); + + do_process_instruction( + mint_to( + &program_id, + &mint_key, + &account_key, + &mint_owner_key, + &[], + 100, + ) + .unwrap(), + vec![ + &mut mint_account, + &mut account_account, + &mut mint_owner_account, + ], + ) + .unwrap(); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.amount, u64::MAX); + + // manipulate account balance to attempt overflow transfer + let mut account = Account::unpack_unchecked(&account2_account.data).unwrap(); + account.amount = 1; + Account::pack(account, &mut account2_account.data).unwrap(); + + assert_eq!( + Err(TokenError::Overflow.into()), + do_process_instruction( + transfer( + &program_id, + &account2_key, + &account_key, + &owner2_key, + &[], + 1, + ) + .unwrap(), + vec![ + &mut account2_account, + &mut account_account, + &mut owner2_account, + ], + ) + ); + } + + #[test] + fn test_frozen() { + let program_id = crate::id(); + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account2_key = Pubkey::new_unique(); + let mut account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mut rent_sysvar = rent_sysvar(); + + // create new mint and fund first account + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + // create account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // create another account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account2_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account2_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // fund first account + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(), + vec![&mut mint_account, &mut account_account, &mut owner_account], + ) + .unwrap(); + + // no transfer if either account is frozen + let mut account = Account::unpack_unchecked(&account2_account.data).unwrap(); + account.state = AccountState::Frozen; + Account::pack(account, &mut account2_account.data).unwrap(); + assert_eq!( + Err(TokenError::AccountFrozen.into()), + do_process_instruction( + transfer( + &program_id, + &account_key, + &account2_key, + &owner_key, + &[], + 500, + ) + .unwrap(), + vec![ + &mut account_account, + &mut account2_account, + &mut owner_account, + ], + ) + ); + + let mut account = Account::unpack_unchecked(&account_account.data).unwrap(); + account.state = AccountState::Initialized; + Account::pack(account, &mut account_account.data).unwrap(); + let mut account = Account::unpack_unchecked(&account2_account.data).unwrap(); + account.state = AccountState::Frozen; + Account::pack(account, &mut account2_account.data).unwrap(); + assert_eq!( + Err(TokenError::AccountFrozen.into()), + do_process_instruction( + transfer( + &program_id, + &account_key, + &account2_key, + &owner_key, + &[], + 500, + ) + .unwrap(), + vec![ + &mut account_account, + &mut account2_account, + &mut owner_account, + ], + ) + ); + + // no approve if account is frozen + let mut account = Account::unpack_unchecked(&account_account.data).unwrap(); + account.state = AccountState::Frozen; + Account::pack(account, &mut account_account.data).unwrap(); + let delegate_key = Pubkey::new_unique(); + let mut delegate_account = SolanaAccount::default(); + assert_eq!( + Err(TokenError::AccountFrozen.into()), + do_process_instruction( + approve( + &program_id, + &account_key, + &delegate_key, + &owner_key, + &[], + 100 + ) + .unwrap(), + vec![ + &mut account_account, + &mut delegate_account, + &mut owner_account, + ], + ) + ); + + // no revoke if account is frozen + let mut account = Account::unpack_unchecked(&account_account.data).unwrap(); + account.delegate = COption::Some(delegate_key); + account.delegated_amount = 100; + Account::pack(account, &mut account_account.data).unwrap(); + assert_eq!( + Err(TokenError::AccountFrozen.into()), + do_process_instruction( + revoke(&TOKEN_PROGRAM_ID, &account_key, &owner_key, &[]).unwrap(), + vec![&mut account_account, &mut owner_account], + ) + ); + + // no set authority if account is frozen + let new_owner_key = Pubkey::new_unique(); + assert_eq!( + Err(TokenError::AccountFrozen.into()), + do_process_instruction( + set_authority( + &program_id, + &account_key, + Some(&new_owner_key), + AuthorityType::AccountOwner, + &owner_key, + &[] + ) + .unwrap(), + vec![&mut account_account, &mut owner_account,], + ) + ); + + // no mint_to if destination account is frozen + assert_eq!( + Err(TokenError::AccountFrozen.into()), + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account_key, &owner_key, &[], 100).unwrap(), + vec![&mut mint_account, &mut account_account, &mut owner_account,], + ) + ); + + // no burn if account is frozen + assert_eq!( + Err(TokenError::AccountFrozen.into()), + do_process_instruction( + burn(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[], 100).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + ); + } + + #[test] + fn test_freeze_thaw_dups() { + let program_id = crate::id(); + let account1_key = Pubkey::new_unique(); + let mut account1_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account1_info: AccountInfo = (&account1_key, true, &mut account1_account).into(); + let owner_key = Pubkey::new_unique(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint_info: AccountInfo = (&mint_key, true, &mut mint_account).into(); + let rent_key = rent::id(); + let mut rent_sysvar = rent_sysvar(); + let rent_info: AccountInfo = (&rent_key, false, &mut rent_sysvar).into(); + + // create mint + do_process_instruction_dups( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, Some(&account1_key), 2).unwrap(), + vec![mint_info.clone(), rent_info.clone()], + ) + .unwrap(); + + // create account + do_process_instruction_dups( + initialize_account(&TOKEN_PROGRAM_ID, &account1_key, &mint_key, &account1_key).unwrap(), + vec![ + account1_info.clone(), + mint_info.clone(), + account1_info.clone(), + rent_info.clone(), + ], + ) + .unwrap(); + + // freeze where mint freeze_authority is account + do_process_instruction_dups( + freeze_account(&TOKEN_PROGRAM_ID, &account1_key, &mint_key, &account1_key, &[]).unwrap(), + vec![ + account1_info.clone(), + mint_info.clone(), + account1_info.clone(), + ], + ) + .unwrap(); + + // thaw where mint freeze_authority is account + let mut account = Account::unpack_unchecked(&account1_info.data.borrow()).unwrap(); + account.state = AccountState::Frozen; + Account::pack(account, &mut account1_info.data.borrow_mut()).unwrap(); + do_process_instruction_dups( + thaw_account(&TOKEN_PROGRAM_ID, &account1_key, &mint_key, &account1_key, &[]).unwrap(), + vec![ + account1_info.clone(), + mint_info.clone(), + account1_info.clone(), + ], + ) + .unwrap(); + } + + #[test] + fn test_freeze_account() { + let program_id = crate::id(); + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let account_owner_key = Pubkey::new_unique(); + let mut account_owner_account = SolanaAccount::default(); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let owner2_key = Pubkey::new_unique(); + let mut owner2_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mut rent_sysvar = rent_sysvar(); + + // create new mint with owner different from account owner + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + // create account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &account_owner_key).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut account_owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // mint to account + do_process_instruction( + mint_to(&TOKEN_PROGRAM_ID, &mint_key, &account_key, &owner_key, &[], 1000).unwrap(), + vec![&mut mint_account, &mut account_account, &mut owner_account], + ) + .unwrap(); + + // mint cannot freeze + assert_eq!( + Err(TokenError::MintCannotFreeze.into()), + do_process_instruction( + freeze_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[]).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + ); + + // missing freeze_authority + let mut mint = Mint::unpack_unchecked(&mint_account.data).unwrap(); + mint.freeze_authority = COption::Some(owner_key); + Mint::pack(mint, &mut mint_account.data).unwrap(); + assert_eq!( + Err(TokenError::OwnerMismatch.into()), + do_process_instruction( + freeze_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner2_key, &[]).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner2_account], + ) + ); + + // check explicit thaw + assert_eq!( + Err(TokenError::InvalidState.into()), + do_process_instruction( + thaw_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner2_key, &[]).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner2_account], + ) + ); + + // freeze + do_process_instruction( + freeze_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[]).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + .unwrap(); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.state, AccountState::Frozen); + + // check explicit freeze + assert_eq!( + Err(TokenError::InvalidState.into()), + do_process_instruction( + freeze_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[]).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + ); + + // check thaw authority + assert_eq!( + Err(TokenError::OwnerMismatch.into()), + do_process_instruction( + thaw_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner2_key, &[]).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner2_account], + ) + ); + + // thaw + do_process_instruction( + thaw_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key, &[]).unwrap(), + vec![&mut account_account, &mut mint_account, &mut owner_account], + ) + .unwrap(); + let account = Account::unpack_unchecked(&account_account.data).unwrap(); + assert_eq!(account.state, AccountState::Initialized); + } + + #[test] + fn test_initialize_account2_and_3() { + let program_id = crate::id(); + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let mut account2_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let mut account3_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mut rent_sysvar = rent_sysvar(); + + // create mint + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + do_process_instruction( + initialize_account2(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![&mut account2_account, &mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + assert_eq!(account_account, account2_account); + + do_process_instruction( + initialize_account3(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![&mut account3_account, &mut mint_account], + ) + .unwrap(); + + assert_eq!(account_account, account3_account); + } + + #[test] + fn test_sync_native() { + let program_id = crate::id(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let native_account_key = Pubkey::new_unique(); + let lamports = 40; + let mut native_account = SolanaAccount::new( + account_minimum_balance() + lamports, + Account::get_packed_len(), + &program_id, + ); + let non_native_account_key = Pubkey::new_unique(); + let mut non_native_account = SolanaAccount::new( + account_minimum_balance() + 50, + Account::get_packed_len(), + &program_id, + ); + + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let mut rent_sysvar = rent_sysvar(); + + // initialize non-native mint + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + // initialize non-native account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &non_native_account_key, &mint_key, &owner_key) + .unwrap(), + vec![ + &mut non_native_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + let account = Account::unpack_unchecked(&non_native_account.data).unwrap(); + assert!(!account.is_native()); + assert_eq!(account.amount, 0); + + // fail sync non-native + assert_eq!( + Err(TokenError::NonNativeNotSupported.into()), + do_process_instruction( + sync_native(&TOKEN_PROGRAM_ID, &non_native_account_key,).unwrap(), + vec![&mut non_native_account], + ) + ); + + // fail sync uninitialized + assert_eq!( + Err(ProgramError::UninitializedAccount), + do_process_instruction( + sync_native(&TOKEN_PROGRAM_ID, &native_account_key,).unwrap(), + vec![&mut native_account], + ) + ); + + // wrap native account + do_process_instruction( + initialize_account( + &program_id, + &native_account_key, + &crate::native_mint::id(), + &owner_key, + ) + .unwrap(), + vec![ + &mut native_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // fail sync, not owned by program + let not_program_id = Pubkey::new_unique(); + native_account.owner = not_program_id; + assert_eq!( + Err(ProgramError::IncorrectProgramId), + do_process_instruction( + sync_native(&TOKEN_PROGRAM_ID, &native_account_key,).unwrap(), + vec![&mut native_account], + ) + ); + native_account.owner = program_id; + + let account = Account::unpack_unchecked(&native_account.data).unwrap(); + assert!(account.is_native()); + assert_eq!(account.amount, lamports); + + // sync, no change + do_process_instruction( + sync_native(&TOKEN_PROGRAM_ID, &native_account_key).unwrap(), + vec![&mut native_account], + ) + .unwrap(); + let account = Account::unpack_unchecked(&native_account.data).unwrap(); + assert_eq!(account.amount, lamports); + + // transfer sol + let new_lamports = lamports + 50; + native_account.lamports = account_minimum_balance() + new_lamports; + + // success sync + do_process_instruction( + sync_native(&TOKEN_PROGRAM_ID, &native_account_key).unwrap(), + vec![&mut native_account], + ) + .unwrap(); + let account = Account::unpack_unchecked(&native_account.data).unwrap(); + assert_eq!(account.amount, new_lamports); + + // reduce sol + native_account.lamports -= 1; + + // fail sync + assert_eq!( + Err(TokenError::InvalidState.into()), + do_process_instruction( + sync_native(&TOKEN_PROGRAM_ID, &native_account_key,).unwrap(), + vec![&mut native_account], + ) + ); + } + + #[test] + #[serial] + fn test_get_account_data_size() { + // see integration tests for return-data validity + let program_id = crate::id(); + let owner_key = Pubkey::new_unique(); + let mut rent_sysvar = rent_sysvar(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mint_key = Pubkey::new_unique(); + // fail if an invalid mint is passed in + assert_eq!( + Err(TokenError::InvalidMint.into()), + do_process_instruction( + get_account_data_size(&TOKEN_PROGRAM_ID, &mint_key).unwrap(), + vec![&mut mint_account], + ) + ); + + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + set_expected_data(Account::LEN.to_le_bytes().to_vec()); + do_process_instruction( + get_account_data_size(&TOKEN_PROGRAM_ID, &mint_key).unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + } + + #[test] + fn test_initialize_immutable_owner() { + let program_id = crate::id(); + let account_key = Pubkey::new_unique(); + let mut account_account = SolanaAccount::new( + account_minimum_balance(), + Account::get_packed_len(), + &program_id, + ); + let owner_key = Pubkey::new_unique(); + let mut owner_account = SolanaAccount::default(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mut rent_sysvar = rent_sysvar(); + + // create mint + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + // success initialize immutable + do_process_instruction( + initialize_immutable_owner(&TOKEN_PROGRAM_ID, &account_key).unwrap(), + vec![&mut account_account], + ) + .unwrap(); + + // create account + do_process_instruction( + initialize_account(&TOKEN_PROGRAM_ID, &account_key, &mint_key, &owner_key).unwrap(), + vec![ + &mut account_account, + &mut mint_account, + &mut owner_account, + &mut rent_sysvar, + ], + ) + .unwrap(); + + // fail post-init + assert_eq!( + Err(TokenError::AlreadyInUse.into()), + do_process_instruction( + initialize_immutable_owner(&TOKEN_PROGRAM_ID, &account_key).unwrap(), + vec![&mut account_account], + ) + ); + } + + #[test] + #[serial] + fn test_amount_to_ui_amount() { + let program_id = crate::id(); + let owner_key = Pubkey::new_unique(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mut rent_sysvar = rent_sysvar(); + + // fail if an invalid mint is passed in + assert_eq!( + Err(TokenError::InvalidMint.into()), + do_process_instruction( + amount_to_ui_amount(&TOKEN_PROGRAM_ID, &mint_key, 110).unwrap(), + vec![&mut mint_account], + ) + ); + + // create mint + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + set_expected_data("0.23".as_bytes().to_vec()); + do_process_instruction( + amount_to_ui_amount(&TOKEN_PROGRAM_ID, &mint_key, 23).unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data("1.1".as_bytes().to_vec()); + do_process_instruction( + amount_to_ui_amount(&TOKEN_PROGRAM_ID, &mint_key, 110).unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data("42".as_bytes().to_vec()); + do_process_instruction( + amount_to_ui_amount(&TOKEN_PROGRAM_ID, &mint_key, 4200).unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data("0".as_bytes().to_vec()); + do_process_instruction( + amount_to_ui_amount(&TOKEN_PROGRAM_ID, &mint_key, 0).unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + } + + #[test] + #[serial] + fn test_ui_amount_to_amount() { + let program_id = crate::id(); + let owner_key = Pubkey::new_unique(); + let mint_key = Pubkey::new_unique(); + let mut mint_account = + SolanaAccount::new(mint_minimum_balance(), Mint::get_packed_len(), &program_id); + let mut rent_sysvar = rent_sysvar(); + + // fail if an invalid mint is passed in + assert_eq!( + Err(TokenError::InvalidMint.into()), + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "1.1").unwrap(), + vec![&mut mint_account], + ) + ); + + // create mint + do_process_instruction( + initialize_mint(&TOKEN_PROGRAM_ID, &mint_key, &owner_key, None, 2).unwrap(), + vec![&mut mint_account, &mut rent_sysvar], + ) + .unwrap(); + + set_expected_data(23u64.to_le_bytes().to_vec()); + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "0.23").unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data(20u64.to_le_bytes().to_vec()); + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "0.20").unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data(20u64.to_le_bytes().to_vec()); + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "0.2000").unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data(20u64.to_le_bytes().to_vec()); + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, ".20").unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data(110u64.to_le_bytes().to_vec()); + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "1.1").unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data(110u64.to_le_bytes().to_vec()); + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "1.10").unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data(4200u64.to_le_bytes().to_vec()); + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "42").unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data(4200u64.to_le_bytes().to_vec()); + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "42.").unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + set_expected_data(0u64.to_le_bytes().to_vec()); + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "0").unwrap(), + vec![&mut mint_account], + ) + .unwrap(); + + // fail if invalid ui_amount passed in + assert_eq!( + Err(ProgramError::InvalidArgument), + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "").unwrap(), + vec![&mut mint_account], + ) + ); + assert_eq!( + Err(ProgramError::InvalidArgument), + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, ".").unwrap(), + vec![&mut mint_account], + ) + ); + assert_eq!( + Err(ProgramError::InvalidArgument), + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "0.111").unwrap(), + vec![&mut mint_account], + ) + ); + assert_eq!( + Err(ProgramError::InvalidArgument), + do_process_instruction( + ui_amount_to_amount(&TOKEN_PROGRAM_ID, &mint_key, "0.t").unwrap(), + vec![&mut mint_account], + ) + ); + } +*/