From fcd0d096e0bb98c8cfcb8a6ddae132973f7b1752 Mon Sep 17 00:00:00 2001 From: lispking Date: Wed, 7 Jan 2026 16:50:21 +0800 Subject: [PATCH 1/4] feat: Add mollusk testing framework module - Introduce mollusk program loader and test context - Add helpers and definition modules for test infrastructure - Update all test stages to use new mollusk-based testing --- Cargo.lock | 3065 ++++++++++++++++- Cargo.toml | 24 +- README.md | 125 +- src/definition.rs | 39 + src/helpers.rs | 428 +++ src/main.rs | 2 + src/mollusk/mod.rs | 107 + src/mollusk/program_loader.rs | 276 ++ src/mollusk/test_context.rs | 258 ++ src/stages/base/at4.rs | 2 +- src/stages/base/be1.rs | 2 +- src/stages/base/cp6.rs | 2 +- src/stages/base/rs2.rs | 2 +- src/stages/base/sm3.rs | 2 +- src/stages/base/st5.rs | 2 +- src/stages/base/tt7.rs | 2 +- .../extensions/account_structure/as1.rs | 16 +- .../extensions/account_structure/as2.rs | 2 +- .../extensions/account_structure/as3.rs | 16 +- .../extensions/account_structure/as4.rs | 16 +- src/stages/extensions/interest/in1.rs | 16 +- src/stages/extensions/interest/in2.rs | 16 +- src/stages/extensions/interest/in3.rs | 2 +- src/stages/extensions/interest/in4.rs | 2 +- src/stages/extensions/lending_core/lc1.rs | 2 +- src/stages/extensions/lending_core/lc2.rs | 2 +- src/stages/extensions/lending_core/lc3.rs | 16 +- src/stages/extensions/lending_core/lc4.rs | 2 +- src/stages/extensions/liquidation/li1.rs | 16 +- src/stages/extensions/liquidation/li2.rs | 16 +- src/stages/extensions/liquidation/li3.rs | 16 +- src/stages/extensions/liquidation/li4.rs | 2 +- src/stages/extensions/liquidation/li5.rs | 2 +- src/stages/extensions/oracle/or1.rs | 2 +- src/stages/extensions/oracle/or2.rs | 2 +- src/stages/extensions/oracle/or3.rs | 2 +- src/stages/extensions/oracle/or4.rs | 2 +- src/stages/extensions/pda/pa1.rs | 16 +- src/stages/extensions/pda/pa2.rs | 2 +- src/stages/extensions/pda/pa3.rs | 16 +- src/stages/extensions/pda/pa4.rs | 16 +- src/stages/extensions/security/se1.rs | 2 +- src/stages/extensions/security/se2.rs | 16 +- src/stages/extensions/security/se3.rs | 2 +- src/stages/extensions/security/se4.rs | 2 +- src/stages/extensions/treasury/tr1.rs | 16 +- src/stages/extensions/treasury/tr2.rs | 16 +- src/stages/extensions/treasury/tr3.rs | 16 +- src/stages/extensions/treasury/tr4.rs | 2 +- 49 files changed, 4537 insertions(+), 91 deletions(-) create mode 100644 src/helpers.rs create mode 100644 src/mollusk/mod.rs create mode 100644 src/mollusk/program_loader.rs create mode 100644 src/mollusk/test_context.rs diff --git a/Cargo.lock b/Cargo.lock index 5a6defb..9301123 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,93 +2,2851 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "agave-feature-set" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d4a155f30015eab7e4a9ba2bcf9e1078c70707230668dc577e41830d97d0313" +dependencies = [ + "ahash", + "solana-epoch-schedule", + "solana-hash 3.1.0", + "solana-pubkey 3.0.0", + "solana-sha256-hasher", + "solana-svm-feature-set", +] + +[[package]] +name = "agave-syscalls" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c18d9f932913dc5c7a6258b453ce7d42ed465001cd054b2a5f2c8e8d2a5e2bc0" +dependencies = [ + "bincode", + "libsecp256k1", + "num-traits", + "solana-account", + "solana-account-info", + "solana-big-mod-exp", + "solana-blake3-hasher", + "solana-bn254", + "solana-clock", + "solana-cpi", + "solana-curve25519", + "solana-hash 3.1.0", + "solana-instruction", + "solana-keccak-hasher", + "solana-loader-v3-interface", + "solana-poseidon", + "solana-program-entrypoint", + "solana-program-runtime", + "solana-pubkey 3.0.0", + "solana-sbpf", + "solana-sdk-ids", + "solana-secp256k1-recover", + "solana-sha256-hasher", + "solana-stable-layout", + "solana-stake-interface", + "solana-svm-callback", + "solana-svm-feature-set", + "solana-svm-log-collector", + "solana-svm-measure", + "solana-svm-timings", + "solana-svm-type-overrides", + "solana-sysvar", + "solana-sysvar-id", + "solana-transaction-context", + "thiserror 2.0.17", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.4", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-std 0.4.0", +] + +[[package]] +name = "ark-bn254" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" +dependencies = [ + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-std 0.5.0", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff 0.4.2", + "ark-poly 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" +dependencies = [ + "ahash", + "ark-ff 0.5.0", + "ark-poly 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.5", + "itertools 0.13.0", + "num-bigint 0.4.6", + "num-integer", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint 0.4.6", + "num-traits", + "paste", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.106", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-poly" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" +dependencies = [ + "ahash", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "educe", + "fnv", + "hashbrown 0.15.5", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive 0.4.2", + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint 0.4.6", +] + +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-serialize-derive 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "num-bigint 0.4.6", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytemuck" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[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.106", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "eager" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abe71d579d1812060163dff96056261deb5bf6729b100fa2e36a68b9649ba3d3" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "enum-iterator" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "enum-ordinalize" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "env_filter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "find-msvc-tools" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" + +[[package]] +name = "five8" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75b8549488b4715defcb0d8a8a1c1c76a80661b5fa106b4ca0e7fce59d7d875" +dependencies = [ + "five8_core 0.1.2", +] + +[[package]] +name = "five8" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f76610e969fa1784327ded240f1e28a3fd9520c9cec93b636fcf62dd37f772" +dependencies = [ + "five8_core 1.0.0", +] + +[[package]] +name = "five8_const" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a0f1728185f277989ca573a402716ae0beaaea3f76a8ff87ef9dd8fb19436c5" +dependencies = [ + "five8_core 1.0.0", +] + +[[package]] +name = "five8_core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" + +[[package]] +name = "five8_core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059c31d7d36c43fe39d89e55711858b4da8be7eb6dabac23c7289b1a19489406" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "indexmap" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +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 = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a87d9b8105c23642f50cbbae03d1f75d8422c5cb98ce7ee9271f7ff7505be6b8" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b787bebb543f8969132630c51fd0afab173a86c6abae56ff3b9e5e3e3f9f6e58" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.9", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.178" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254 0.4.0", + "ark-ff 0.4.2", + "num-bigint 0.4.6", + "thiserror 1.0.69", +] + +[[package]] +name = "light-poseidon" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47a1ccadd0bb5a32c196da536fd72c59183de24a055f6bf0513bf845fefab862" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ff 0.5.0", + "num-bigint 0.4.6", + "thiserror 1.0.69", +] + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "mollusk-svm" +version = "0.9.0" +dependencies = [ + "agave-feature-set", + "agave-syscalls", + "bincode", + "mollusk-svm-error", + "mollusk-svm-result", + "solana-account", + "solana-bpf-loader-program", + "solana-clock", + "solana-compute-budget", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-hash 3.1.0", + "solana-instruction", + "solana-instruction-error", + "solana-instructions-sysvar", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-logger", + "solana-message", + "solana-precompile-error", + "solana-program-error", + "solana-program-runtime", + "solana-pubkey 4.0.0", + "solana-rent", + "solana-sdk-ids", + "solana-slot-hashes", + "solana-stake-interface", + "solana-svm-callback", + "solana-svm-log-collector", + "solana-svm-timings", + "solana-svm-transaction", + "solana-system-program", + "solana-sysvar", + "solana-sysvar-id", + "solana-transaction-context", + "solana-transaction-error", +] + +[[package]] +name = "mollusk-svm-error" +version = "0.9.0" +dependencies = [ + "solana-pubkey 4.0.0", + "thiserror 1.0.69", +] + +[[package]] +name = "mollusk-svm-programs-token" +version = "0.9.0" +dependencies = [ + "mollusk-svm", + "solana-account", + "solana-program-pack", + "solana-pubkey 4.0.0", + "solana-rent", + "spl-associated-token-account-interface", + "spl-token-interface", +] + +[[package]] +name = "mollusk-svm-result" +version = "0.9.0" +dependencies = [ + "solana-account", + "solana-instruction", + "solana-program-error", + "solana-pubkey 4.0.0", + "solana-rent", + "solana-transaction-error", +] + +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint 0.2.6", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint 0.2.6", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percentage" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd23b938276f14057220b707937bcb42fa76dda7560e57a2da30cb52d557937" +dependencies = [ + "num", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "portable-atomic" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qualifier_attr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "serde_json" +version = "1.0.143" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "solana-account" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e0ac2a81ae17e1b3570deb50242ab4cfde50b848b898f57288b6271cc7b71f" +dependencies = [ + "bincode", + "qualifier_attr", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-instruction-error", + "solana-pubkey 4.0.0", + "solana-sdk-ids", + "solana-sysvar", +] + +[[package]] +name = "solana-account-info" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3397241392f5756925029acaa8515dc70fcbe3d8059d4885d7d6533baf64fd" +dependencies = [ + "solana-address 2.0.0", + "solana-program-error", + "solana-program-memory", +] + +[[package]] +name = "solana-address" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2ecac8e1b7f74c2baa9e774c42817e3e75b20787134b76cc4d45e8a604488f5" +dependencies = [ + "solana-address 2.0.0", +] + +[[package]] +name = "solana-address" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37320fd2945c5d654b2c6210624a52d66c3f1f73b653ed211ab91a703b35bdd" +dependencies = [ + "borsh", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek", + "five8 1.0.0", + "five8_const", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-define-syscall 4.0.1", + "solana-program-error", + "solana-sanitize", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-atomic-u64" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a933ff1e50aff72d02173cfcd7511bd8540b027ee720b75f353f594f834216d0" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "solana-big-mod-exp" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c80fb6d791b3925d5ec4bf23a7c169ef5090c013059ec3ed7d0b2c04efa085" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "solana-define-syscall 3.0.0", +] + +[[package]] +name = "solana-bincode" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "278a1a5bad62cd9da89ac8d4b7ec444e83caa8ae96aa656dfc27684b28d49a5d" +dependencies = [ + "bincode", + "serde_core", + "solana-instruction-error", +] + +[[package]] +name = "solana-blake3-hasher" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7116e1d942a2432ca3f514625104757ab8a56233787e95144c93950029e31176" +dependencies = [ + "blake3", + "solana-define-syscall 4.0.1", + "solana-hash 4.0.1", +] + +[[package]] +name = "solana-bn254" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d08583be08d2d5f19aa21efbb6fbdb968ba7fd0de74562441437a7d776772bf" +dependencies = [ + "ark-bn254 0.4.0", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "bytemuck", + "solana-define-syscall 3.0.0", + "thiserror 2.0.17", +] + +[[package]] +name = "solana-bpf-loader-program" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7ea871a1450cc7a2b459b18a3bdc0f3db23aab283b19c969a76c225f35d8a69" +dependencies = [ + "agave-syscalls", + "bincode", + "qualifier_attr", + "solana-account", + "solana-bincode", + "solana-clock", + "solana-instruction", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-packet", + "solana-program-entrypoint", + "solana-program-runtime", + "solana-pubkey 3.0.0", + "solana-sbpf", + "solana-sdk-ids", + "solana-svm-feature-set", + "solana-svm-log-collector", + "solana-svm-measure", + "solana-svm-type-overrides", + "solana-system-interface", + "solana-transaction-context", +] + +[[package]] +name = "solana-clock" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb62e9381182459a4520b5fe7fb22d423cae736239a6427fc398a88743d0ed59" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-compute-budget" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864dc20438899a9e942e4d5188e615396426c051000842add53c08da2f51d548" +dependencies = [ + "solana-fee-structure", + "solana-program-runtime", +] + +[[package]] +name = "solana-cpi" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dea26709d867aada85d0d3617db0944215c8bb28d3745b912de7db13a23280c" +dependencies = [ + "solana-account-info", + "solana-define-syscall 4.0.1", + "solana-instruction", + "solana-program-error", + "solana-pubkey 4.0.0", + "solana-stable-layout", +] + +[[package]] +name = "solana-curve25519" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebca352e7716ff1a0877272f87c772c958489c1d568a92d318dc0c75939d2884" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek", + "solana-define-syscall 3.0.0", + "subtle", + "thiserror 2.0.17", +] + +[[package]] +name = "solana-define-syscall" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9697086a4e102d28a156b8d6b521730335d6951bd39a5e766512bbe09007cee" + +[[package]] +name = "solana-define-syscall" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e5b1c0bc1d4a4d10c88a4100499d954c09d3fecfae4912c1a074dff68b1738" + +[[package]] +name = "solana-epoch-rewards" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b319a4ed70390af911090c020571f0ff1f4ec432522d05ab89f5c08080381995" +dependencies = [ + "serde", + "serde_derive", + "solana-hash 3.1.0", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-schedule" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5481e72cc4d52c169db73e4c0cd16de8bc943078aac587ec4817a75cc6388f" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-fee-calculator" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a73cc03ca4bed871ca174558108835f8323e85917bb38b9c81c7af2ab853efe" +dependencies = [ + "log", + "serde", + "serde_derive", +] + +[[package]] +name = "solana-fee-structure" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2abdb1223eea8ec64136f39cb1ffcf257e00f915c957c35c0dd9e3f4e700b0" + +[[package]] +name = "solana-hash" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "337c246447142f660f778cf6cb582beba8e28deb05b3b24bfb9ffd7c562e5f41" +dependencies = [ + "solana-hash 4.0.1", +] + +[[package]] +name = "solana-hash" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a5d48a6ee7b91fc7b998944ab026ed7b3e2fc8ee3bc58452644a86c2648152f" +dependencies = [ + "borsh", + "bytemuck", + "bytemuck_derive", + "five8 1.0.0", + "serde", + "serde_derive", + "solana-atomic-u64", + "solana-sanitize", +] + +[[package]] +name = "solana-instruction" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee1b699a2c1518028a9982e255e0eca10c44d90006542d9d7f9f40dbce3f7c78" +dependencies = [ + "bincode", + "borsh", + "serde", + "serde_derive", + "solana-define-syscall 4.0.1", + "solana-instruction-error", + "solana-pubkey 4.0.0", +] + +[[package]] +name = "solana-instruction-error" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b04259e03c05faf38a8c24217b5cfe4c90572ae6184ab49cddb1584fdd756d3f" +dependencies = [ + "num-traits", + "serde", + "serde_derive", + "solana-program-error", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ddf67876c541aa1e21ee1acae35c95c6fbc61119814bfef70579317a5e26955" +dependencies = [ + "bitflags", + "solana-account-info", + "solana-instruction", + "solana-instruction-error", + "solana-program-error", + "solana-pubkey 3.0.0", + "solana-sanitize", + "solana-sdk-ids", + "solana-serialize-utils", + "solana-sysvar-id", +] + +[[package]] +name = "solana-keccak-hasher" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed1c0d16d6fdeba12291a1f068cdf0d479d9bff1141bf44afd7aa9d485f65ef8" +dependencies = [ + "sha3", + "solana-define-syscall 4.0.1", + "solana-hash 4.0.1", +] + +[[package]] +name = "solana-last-restart-slot" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcda154ec827f5fc1e4da0af3417951b7e9b8157540f81f936c4a8b1156134d0" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-lending-program-tester" +version = "0.1.0" +dependencies = [ + "mollusk-svm", + "mollusk-svm-programs-token", + "serde", + "serde_json", + "sha2 0.10.9", + "solana-account", + "solana-clock", + "solana-instruction", + "solana-instruction-error", + "solana-program-option", + "solana-program-pack", + "solana-pubkey 4.0.0", + "solana-rent", + "solana-system-interface", + "solana-system-program", + "spl-associated-token-account-interface", + "spl-token-interface", + "tester", + "thiserror 1.0.69", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee44c9b1328c5c712c68966fb8de07b47f3e7bac006e74ddd1bb053d3e46e5d" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey 3.0.0", + "solana-sdk-ids", +] + +[[package]] +name = "solana-loader-v4-interface" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c948b33ff81fa89699911b207059e493defdba9647eaf18f23abdf3674e0fb" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-logger" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef7421d1092680d72065edbf5c7605856719b021bf5f173656c71febcdd5d003" +dependencies = [ + "env_logger", + "lazy_static", + "libc", + "log", + "signal-hook", +] + +[[package]] +name = "solana-message" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85666605c9fd727f865ed381665db0a8fc29f984a030ecc1e40f43bfb2541623" +dependencies = [ + "lazy_static", + "solana-address 1.1.0", + "solana-hash 3.1.0", + "solana-instruction", + "solana-sanitize", + "solana-sdk-ids", + "solana-transaction-error", +] + +[[package]] +name = "solana-msg" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "264275c556ea7e22b9d3f87d56305546a38d4eee8ec884f3b126236cb7dcbbb4" +dependencies = [ + "solana-define-syscall 3.0.0", +] + +[[package]] +name = "solana-nonce" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abbdc6c8caf1c08db9f36a50967539d0f72b9f1d4aea04fec5430f532e5afadc" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator", + "solana-hash 3.1.0", + "solana-pubkey 3.0.0", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-nonce-account" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "805fd25b29e5a1a0e6c3dd6320c9da80f275fbe4ff6e392617c303a2085c435e" +dependencies = [ + "solana-account", + "solana-hash 3.1.0", + "solana-nonce", + "solana-sdk-ids", +] + +[[package]] +name = "solana-packet" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edf2f25743c95229ac0fdc32f8f5893ef738dbf332c669e9861d33ddb0f469d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "solana-poseidon" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa6f89aa38e3010f343900e154a319a20276713758dad5a732fe52afd04dba87" +dependencies = [ + "ark-bn254 0.4.0", + "ark-bn254 0.5.0", + "light-poseidon 0.2.0", + "light-poseidon 0.4.0", + "solana-define-syscall 3.0.0", + "thiserror 2.0.17", +] + +[[package]] +name = "solana-precompile-error" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cafcd950de74c6c39d55dc8ca108bbb007799842ab370ef26cf45a34453c31e1" +dependencies = [ + "num-traits", +] + +[[package]] +name = "solana-program-entrypoint" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c9b0a1ff494e05f503a08b3d51150b73aa639544631e510279d6375f290997" +dependencies = [ + "solana-account-info", + "solana-define-syscall 4.0.1", + "solana-program-error", + "solana-pubkey 4.0.0", +] + +[[package]] +name = "solana-program-error" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1af32c995a7b692a915bb7414d5f8e838450cf7c70414e763d8abcae7b51f28" + +[[package]] +name = "solana-program-memory" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4068648649653c2c50546e9a7fb761791b5ab0cda054c771bb5808d3a4b9eb52" +dependencies = [ + "solana-define-syscall 4.0.1", +] + +[[package]] +name = "solana-program-option" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e7b4ddb464f274deb4a497712664c3b612e3f5f82471d4e47710fc4ab1c3095" + +[[package]] +name = "solana-program-pack" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c169359de21f6034a63ebf96d6b380980307df17a8d371344ff04a883ec4e9d0" +dependencies = [ + "solana-program-error", +] + +[[package]] +name = "solana-program-runtime" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8738863de0f78036affb1d1dcc4747bf7783f212dc3a646e19ae827ce8f7245d" +dependencies = [ + "base64 0.22.1", + "bincode", + "itertools 0.12.1", + "log", + "percentage", + "rand 0.8.5", + "serde", + "solana-account", + "solana-account-info", + "solana-clock", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-structure", + "solana-hash 3.1.0", + "solana-instruction", + "solana-last-restart-slot", + "solana-loader-v3-interface", + "solana-program-entrypoint", + "solana-pubkey 3.0.0", + "solana-rent", + "solana-sbpf", + "solana-sdk-ids", + "solana-slot-hashes", + "solana-stable-layout", + "solana-stake-interface", + "solana-svm-callback", + "solana-svm-feature-set", + "solana-svm-log-collector", + "solana-svm-measure", + "solana-svm-timings", + "solana-svm-transaction", + "solana-svm-type-overrides", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-transaction-context", + "thiserror 2.0.17", +] + +[[package]] +name = "solana-pubkey" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8909d399deb0851aa524420beeb5646b115fd253ef446e35fe4504c904da3941" +dependencies = [ + "solana-address 1.1.0", +] + +[[package]] +name = "solana-pubkey" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6f7104d456b58e1418c21a8581e89810278d1190f70f27ece7fc0b2c9282a57" +dependencies = [ + "solana-address 2.0.0", +] + +[[package]] +name = "solana-rent" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e860d5499a705369778647e97d760f7670adfb6fc8419dd3d568deccd46d5487" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sanitize" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf09694a0fc14e5ffb18f9b7b7c0f15ecb6eac5b5610bf76a1853459d19daf9" + +[[package]] +name = "solana-sbpf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15b079e08471a9dbfe1e48b2c7439c85aa2a055cbd54eddd8bd257b0a7dbb29" +dependencies = [ + "byteorder", + "combine", + "hash32", + "libc", + "log", + "rand 0.8.5", + "rustc-demangle", + "thiserror 2.0.17", + "winapi", +] + +[[package]] +name = "solana-sdk-ids" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def234c1956ff616d46c9dd953f251fa7096ddbaa6d52b165218de97882b7280" +dependencies = [ + "solana-address 2.0.0", +] + +[[package]] +name = "solana-sdk-macro" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6430000e97083460b71d9fbadc52a2ab2f88f53b3a4c5e58c5ae3640a0e8c00" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "solana-secp256k1-recover" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de18cfdab99eeb940fbedd8c981fa130c0d76252da75d05446f22fae8b51932" +dependencies = [ + "k256", + "solana-define-syscall 4.0.1", + "thiserror 2.0.17", +] [[package]] -name = "memchr" -version = "2.7.5" +name = "solana-serialize-utils" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "56e41dd8feea239516c623a02f0a81c2367f4b604d7965237fed0751aeec33ed" +dependencies = [ + "solana-instruction-error", + "solana-pubkey 3.0.0", + "solana-sanitize", +] [[package]] -name = "once_cell" -version = "1.21.3" +name = "solana-sha256-hasher" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "db7dc3011ea4c0334aaaa7e7128cb390ecf546b28d412e9bf2064680f57f588f" +dependencies = [ + "sha2 0.10.9", + "solana-define-syscall 4.0.1", + "solana-hash 4.0.1", +] [[package]] -name = "pin-project-lite" -version = "0.2.16" +name = "solana-signature" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "4bb8057cc0e9f7b5e89883d49de6f407df655bb6f3a71d0b7baf9986a2218fd9" +dependencies = [ + "five8 0.2.1", + "solana-sanitize", +] [[package]] -name = "proc-macro2" -version = "1.0.101" +name = "solana-slot-hashes" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "80a293f952293281443c04f4d96afd9d547721923d596e92b4377ed2360f1746" dependencies = [ - "unicode-ident", + "serde", + "serde_derive", + "solana-hash 3.1.0", + "solana-sdk-ids", + "solana-sysvar-id", ] [[package]] -name = "quote" -version = "1.0.40" +name = "solana-slot-history" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "f914f6b108f5bba14a280b458d023e3621c9973f27f015a4d755b50e88d89e97" dependencies = [ - "proc-macro2", + "bv", + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sysvar-id", ] [[package]] -name = "ryu" -version = "1.0.20" +name = "solana-stable-layout" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "1da74507795b6e8fb60b7c7306c0c36e2c315805d16eaaf479452661234685ac" +dependencies = [ + "solana-instruction", + "solana-pubkey 3.0.0", +] [[package]] -name = "serde" -version = "1.0.219" +name = "solana-stake-interface" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "b9bc26191b533f9a6e5a14cca05174119819ced680a80febff2f5051a713f0db" dependencies = [ + "num-traits", + "serde", "serde_derive", + "solana-clock", + "solana-cpi", + "solana-instruction", + "solana-program-error", + "solana-pubkey 3.0.0", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", ] [[package]] -name = "serde_derive" -version = "1.0.219" +name = "solana-svm-callback" +version = "3.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "5ace45d73cb921cc451f497a48df290bd784a65c987570a67a4c9f0d0eb11e56" dependencies = [ - "proc-macro2", - "quote", - "syn", + "solana-account", + "solana-clock", + "solana-precompile-error", + "solana-pubkey 3.0.0", ] [[package]] -name = "serde_json" -version = "1.0.143" +name = "solana-svm-feature-set" +version = "3.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "ca638d19ace892ef2bf31af74897fa8828ebf9d6418b46771c67857e66cf5c97" + +[[package]] +name = "solana-svm-log-collector" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d12ad2fa212fcfec7c3fcf94afc51ebe71ff2e757df6c3148a3f0bd8c79e31e" dependencies = [ - "itoa", - "memchr", - "ryu", + "log", +] + +[[package]] +name = "solana-svm-measure" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9eaf2c082f2a54ec06fd3be215dc76329b1441f9bd3e2370ede699b54a554ab" + +[[package]] +name = "solana-svm-timings" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a619a2184b7f8e846a087b2ada41da6c494940f64c12eb6c6b8a869d8959fb" +dependencies = [ + "eager", + "enum-iterator", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "solana-svm-transaction" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206c4b0b8bae22e6bbcc0aff78069bb2f58804f8d953ca6622bc5a0ee82abc7b" +dependencies = [ + "solana-hash 3.1.0", + "solana-message", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "solana-signature", + "solana-transaction", +] + +[[package]] +name = "solana-svm-type-overrides" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30f2f7e41312046fb07a7f4de7bff814501b983f64a34805756ea76f08f6263" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "solana-system-interface" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e1790547bfc3061f1ee68ea9d8dc6c973c02a163697b24263a8e9f2e6d4afa2" +dependencies = [ + "num-traits", "serde", + "serde_derive", + "solana-instruction", + "solana-msg", + "solana-program-error", + "solana-pubkey 3.0.0", ] [[package]] -name = "solana-lending-program-tester" -version = "0.1.0" +name = "solana-system-program" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3abee2737a4b1c578c8d4d3c63017350232f40f5826e47be1f9729ac1fd83f" dependencies = [ + "bincode", + "log", "serde", - "serde_json", - "tester", + "solana-account", + "solana-bincode", + "solana-fee-calculator", + "solana-instruction", + "solana-nonce", + "solana-nonce-account", + "solana-packet", + "solana-program-runtime", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "solana-svm-log-collector", + "solana-svm-type-overrides", + "solana-system-interface", + "solana-sysvar", + "solana-transaction-context", +] + +[[package]] +name = "solana-sysvar" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6690d3dd88f15c21edff68eb391ef8800df7a1f5cec84ee3e8d1abf05affdf74" +dependencies = [ + "base64 0.22.1", + "bincode", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info", + "solana-clock", + "solana-define-syscall 4.0.1", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-calculator", + "solana-hash 4.0.1", + "solana-instruction", + "solana-last-restart-slot", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-pubkey 4.0.0", + "solana-rent", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-slot-hashes", + "solana-slot-history", + "solana-sysvar-id", +] + +[[package]] +name = "solana-sysvar-id" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17358d1e9a13e5b9c2264d301102126cf11a47fd394cdf3dec174fe7bc96e1de" +dependencies = [ + "solana-address 2.0.0", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ceb2efbf427a91b884709ffac4dac29117752ce1e37e9ae04977e450aa0bb76" +dependencies = [ + "solana-address 2.0.0", + "solana-hash 4.0.1", + "solana-instruction", + "solana-instruction-error", + "solana-message", + "solana-sanitize", + "solana-sdk-ids", + "solana-signature", + "solana-transaction-error", +] + +[[package]] +name = "solana-transaction-context" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120863f5edd2f70338482e9719c630c88441f9499d796dbfc68f6d0fa92413df" +dependencies = [ + "bincode", + "qualifier_attr", + "serde", + "solana-account", + "solana-instruction", + "solana-instructions-sysvar", + "solana-pubkey 3.0.0", + "solana-rent", + "solana-sbpf", + "solana-sdk-ids", +] + +[[package]] +name = "solana-transaction-error" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4222065402340d7e6aec9dc3e54d22992ddcf923d91edcd815443c2bfca3144a" +dependencies = [ + "solana-instruction-error", + "solana-sanitize", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "spl-associated-token-account-interface" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6433917b60441d68d99a17e121d9db0ea15a9a69c0e5afa34649cf5ba12612f" +dependencies = [ + "solana-instruction", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "spl-token-interface" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c564ac05a7c8d8b12e988a37d82695b5ba4db376d07ea98bc4882c81f96c7f3" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-instruction", + "solana-program-error", + "solana-program-option", + "solana-program-pack", + "solana-pubkey 3.0.0", + "solana-sdk-ids", + "thiserror 2.0.17", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] @@ -109,28 +2867,93 @@ source = "git+https://github.com/stackclass/tester.git?tag=v0.4.0#ae5431317f0d39 dependencies = [ "serde", "serde_json", - "thiserror", + "thiserror 2.0.17", "tracing", ] [[package]] name = "thiserror" -version = "2.0.16" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "thiserror-impl", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow", ] [[package]] @@ -152,7 +2975,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", ] [[package]] @@ -164,8 +2987,154 @@ dependencies = [ "once_cell", ] +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + [[package]] name = "unicode-ident" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "zerocopy" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] diff --git a/Cargo.toml b/Cargo.toml index 4106cf6..ca1c2b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,28 @@ version = "0.1.0" edition = "2024" [dependencies] -tester = { git = "https://github.com/stackclass/tester.git", tag = "v0.4.0"} +tester = { git = "https://github.com/stackclass/tester.git", tag = "v0.4.0" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +thiserror = "1.0" +sha2 = "0.10" + +# Mollusk dependencies +mollusk-svm = "0.9.0" +mollusk-svm-programs-token = "0.9.0" + +# Solana SDK dependencies +solana-account = "3.2.0" +solana-clock = "3.0" +solana-instruction = "3.0" +solana-instruction-error = "2.0" +solana-program-option = "3.0" +solana-pubkey = "4.0" +solana-program-pack = "3.0" +solana-rent = "3.0" +solana-system-interface = "2.0" +solana-system-program = "3.1.0" + +# SPL Token dependencies +spl-token-interface = "2.0.0" +spl-associated-token-account-interface = "2.0.0" diff --git a/README.md b/README.md index bb92f0c..784c648 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,29 @@ # Solana Lending Program Development Challenge Tester This is a program that validates your progress on the "Solana Lending Program -Development" challenge. +Development" challenge using the Mollusk test harness. + +## Overview + +The tester has been enhanced with the Mollusk framework, a lightweight test +harness for Solana programs. This provides: + +- **Fast Execution**: Direct SVM instruction execution without full validator runtime +- **Precise Control**: Explicit account management and instruction validation +- **Better Testing**: Comprehensive checks for account state, lamports, data, and more + +## Architecture + +The tester is organized into the following modules: + +- `src/main.rs` - Entry point that initializes the tester +- `src/definition.rs` - Test case definitions +- `src/stages/` - Test implementations organized by stage +- `src/mollusk/` - Mollusk integration module + - `mod.rs` - Main Mollusk management + - `program_loader.rs` - Program loading utilities + - `test_context.rs` - Test context for state management +- `src/helpers.rs` - Helper functions for testing ## Requirements for binary @@ -12,4 +34,103 @@ Development" challenge. ## User code requirements - A binary named `your_program.sh` that executes the program. -- A file named `stackclass.yml`, with the following values: `debug`. \ No newline at end of file +- A file named `stackclass.yml`, with the following values: `debug`. + +## Building + +```bash +cargo build --release +``` + +## Running Tests + +The tester will automatically load and test the user's lending program using +Mollusk. Ensure the program is built before running tests: + +```bash +cd +anchor build +``` + +## Test Stages + +### Base Stages (7) +1. **be1** - Environment Setup +2. **rs2** - Rust Basics +3. **sm3** - Solana Model +4. **at4** - Anchor Try +5. **st5** - SPL Token Basics +6. **cp6** - Basic Deposit +7. **tt7** - Basic Withdraw + +### Extension Modules (8 modules × 4 stages = 32 cases) + +#### PDA Module +- **pa1** - PDA Concept +- **pa2** - PDA Derivation +- **pa3** - Bump Seeds +- **pa4** - PDA Practice + +#### Treasury Module +- **tr1** - Treasury Intro +- **tr2** - Treasury Creation +- **tr3** - Treasury Security +- **tr4** - Treasury Practice + +#### Account Structure Module +- **as1** - Bank Account +- **as2** - User Account +- **as3** - Account Space +- **as4** - Account Practice + +#### Lending Core Module +- **lc1** - Borrow Basics +- **lc2** - Repay Basics +- **lc3** - LTV Calculation +- **lc4** - Core Practice + +#### Oracle Module +- **or1** - Oracle Concept +- **or2** - Pyth Integration +- **or3** - Price Fetching +- **or4** - Oracle Practice + +#### Liquidation Module +- **li1** - Health Factor +- **li2** - Liquidation Trigger +- **li3** - Liquidation Process +- **li4** - Liquidation Bonus +- **li5** - Liquidation Practice + +#### Interest Module +- **in1** - Interest Basics +- **in2** - Accrued Interest +- **in3** - Rate Models +- **in4** - Interest Practice + +#### Security Module +- **se1** - Common Vulnerabilities +- **se2** - Reentrancy Protection +- **se3** - Account Validation +- **se4** - Security Practice + +## Mollusk Integration + +The tester uses Mollusk for efficient program testing: + +```rust +use crate::mollusk::{create_lending_mollusk, LendingTestContext}; + +// Create Mollusk instance +let mollusk = create_lending_mollusk(&repo_dir)?; +let mut context = LendingTestContext::new(mollusk)?; + +// Create accounts and execute instructions +let user = context.create_funded_account(1_000_000_000); +let instruction = create_lending_instruction(data, accounts); +context.execute_instruction(&instruction)?; +``` + +## License + +See LICENSE file for details. \ No newline at end of file diff --git a/src/definition.rs b/src/definition.rs index 42c4818..1b9a0c7 100644 --- a/src/definition.rs +++ b/src/definition.rs @@ -1,3 +1,23 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Definition module for the lending program tester. +//! +//! This module builds the test definition using the tester framework. +//! The test cases are implemented using the Mollusk test harness for +//! efficient and accurate Solana program testing. + use std::sync::Arc; use tester::{Case, Definition}; @@ -16,11 +36,21 @@ use crate::stages::{ }, }; +/// Build the test definition for the lending program. +/// +/// This function creates a Definition struct that includes all test cases +/// for the lending program challenge. The tests are organized into base +/// stages and extension modules. +/// +/// # Returns +/// +/// * `Definition` - The test definition pub fn build() -> Definition { Definition { executable_name: "your_program.sh".to_string(), legacy_executable_name: None, cases: vec![ + // Base Stages (7 stages) Case::new("be1", Arc::new(be1::test_env_setup)), Case::new("rs2", Arc::new(rs2::test_rust_basics)), Case::new("sm3", Arc::new(sm3::test_solana_model)), @@ -28,35 +58,44 @@ pub fn build() -> Definition { Case::new("st5", Arc::new(st5::test_spl_token_basics)), Case::new("cp6", Arc::new(cp6::test_basic_deposit)), Case::new("tt7", Arc::new(tt7::test_basic_withdraw)), + // Extension Modules (8 modules × 4 stages = 32 cases) + // PDA Module Case::new("pa1", Arc::new(pa1::test_pda_concept)), Case::new("pa2", Arc::new(pa2::test_pda_derivation)), Case::new("pa3", Arc::new(pa3::test_pda_bump_seeds)), Case::new("pa4", Arc::new(pa4::test_pda_practice)), + // Treasury Module Case::new("tr1", Arc::new(tr1::test_treasury_intro)), Case::new("tr2", Arc::new(tr2::test_treasury_creation)), Case::new("tr3", Arc::new(tr3::test_treasury_security)), Case::new("tr4", Arc::new(tr4::test_treasury_practice)), + // Account Structure Module Case::new("as1", Arc::new(as1::test_bank_account)), Case::new("as2", Arc::new(as2::test_user_account)), Case::new("as3", Arc::new(as3::test_account_space)), Case::new("as4", Arc::new(as4::test_account_practice)), + // Lending Core Module Case::new("lc1", Arc::new(lc1::test_borrow_basics)), Case::new("lc2", Arc::new(lc2::test_repay_basics)), Case::new("lc3", Arc::new(lc3::test_ltv_calculation)), Case::new("lc4", Arc::new(lc4::test_core_practice)), + // Oracle Module Case::new("or1", Arc::new(or1::test_oracle_concept)), Case::new("or2", Arc::new(or2::test_pyth_integration)), Case::new("or3", Arc::new(or3::test_price_fetching)), Case::new("or4", Arc::new(or4::test_oracle_practice)), + // Liquidation Module Case::new("li1", Arc::new(li1::test_health_factor)), Case::new("li2", Arc::new(li2::test_liquidation_trigger)), Case::new("li3", Arc::new(li3::test_liquidation_process)), Case::new("li4", Arc::new(li4::test_liquidation_bonus)), Case::new("li5", Arc::new(li5::test_liquidation_practice)), + // Interest Module Case::new("in1", Arc::new(in1::test_interest_basics)), Case::new("in2", Arc::new(in2::test_accrued_interest)), Case::new("in3", Arc::new(in3::test_rate_models)), Case::new("in4", Arc::new(in4::test_interest_practice)), + // Security Module Case::new("se1", Arc::new(se1::test_common_vulnerabilities)), Case::new("se2", Arc::new(se2::test_reentrancy_protection)), Case::new("se3", Arc::new(se3::test_account_validation)), diff --git a/src/helpers.rs b/src/helpers.rs new file mode 100644 index 0000000..6e6f426 --- /dev/null +++ b/src/helpers.rs @@ -0,0 +1,428 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Helper functions for testing the lending program. + +#[allow(dead_code)] +use crate::mollusk::{ + ProgramLoadError, TestContextError, init_test_context, load_lending_program_id, +}; +use mollusk_svm::{program::keyed_account_for_system_program, result::Check}; +use mollusk_svm_programs_token::{associated_token, token}; +use sha2::{Digest, Sha256}; +use solana_account::Account; +use solana_instruction::{AccountMeta, Instruction}; +use solana_pubkey::Pubkey; +use std::{path::Path, str::FromStr}; + +const DEFAULT_LENDING_PROGRAM_ID: &str = "LendZ1111111111111111111111111111111111111"; + +/// Get the repository directory from environment variables. +/// +/// This function reads the `STACKCLASS_REPOSITORY_DIR` environment variable +/// and returns it as a Path. +/// +/// # Returns +/// +/// * `Ok(PathBuf)` - The repository directory path +/// * `Err(ProgramLoadError)` - If the environment variable is not set +pub fn get_repo_dir() -> Result { + std::env::var("STACKCLASS_REPOSITORY_DIR") + .map_err(|_| ProgramLoadError::RepoNotFound(std::path::PathBuf::from("Not set"))) + .map(std::path::PathBuf::from) +} + +/// Create a test error message for reporting to the user. +/// +/// # Arguments +/// +/// * `stage_name` - The name of the test stage +/// * `error` - The error that occurred +/// +/// # Returns +/// +/// * `String` - A formatted error message +#[allow(dead_code)] +pub fn format_test_error(stage_name: &str, error: &TestContextError) -> String { + format!("Test '{}' failed: {}", stage_name, error) +} + +/// Create a success message for reporting to the user. +/// +/// # Arguments +/// +/// * `stage_name` - The name of the test stage +/// +/// # Returns +/// +/// * `String` - A formatted success message +#[allow(dead_code)] +pub fn format_test_success(stage_name: &str) -> String { + format!("Test '{}' passed successfully", stage_name) +} + +/// Create a basic system account with lamports. +/// +/// # Arguments +/// +/// * `lamports` - The amount of lamports +/// +/// # Returns +/// +/// * `Account` - A system account +#[allow(dead_code)] +pub fn create_system_account(lamports: u64) -> Account { + Account { lamports, owner: solana_system_program::id(), ..Default::default() } +} + +/// Create a check for successful execution. +/// +/// # Returns +/// +/// * `Check` - A success check +#[allow(dead_code)] +pub fn success_check() -> Check<'static> { + Check::success() +} + +/// Create a check for account lamports. +/// +/// # Arguments +/// +/// * `pubkey` - The account public key +/// * `expected_lamports` - The expected lamports +/// +/// # Returns +/// +/// * `Check` - A lamports check +#[allow(dead_code)] +pub fn lamports_check(pubkey: &Pubkey, expected_lamports: u64) -> Check<'_> { + Check::account(pubkey).lamports(expected_lamports).build() +} + +/// Create a check for account data. +/// +/// # Arguments +/// +/// * `pubkey` - The account public key +/// * `expected_data` - The expected account data +/// +/// # Returns +/// +/// * `Check` - A data check +#[allow(dead_code)] +pub fn data_check<'a>(pubkey: &'a Pubkey, expected_data: &'a [u8]) -> Check<'a> { + Check::account(pubkey).data(expected_data).build() +} + +/// Create a check for account owner. +/// +/// # Arguments +/// +/// * `pubkey` - The account public key +/// * `expected_owner` - The expected owner +/// +/// # Returns +/// +/// * `Check` - An owner check +#[allow(dead_code)] +pub fn owner_check<'a>(pubkey: &'a Pubkey, expected_owner: &'a Pubkey) -> Check<'a> { + Check::account(pubkey).owner(expected_owner).build() +} + +/// Create a check for account executability. +/// +/// # Arguments +/// +/// * `pubkey` - The account public key +/// * `expected_executable` - The expected executability +/// +/// # Returns +/// +/// * `Check` - An executable check +#[allow(dead_code)] +pub fn executable_check(pubkey: &Pubkey, expected_executable: bool) -> Check<'_> { + Check::account(pubkey).executable(expected_executable).build() +} + +/// Convert a TestContextError to a tester::CaseError. +/// +/// # Arguments +/// +/// * `error` - The TestContextError to convert +/// +/// # Returns +/// +/// * `tester::CaseError` - The converted error +pub fn to_case_error(error: TestContextError) -> tester::CaseError { + Box::new(error) as Box +} + +/// Convert a ProgramLoadError to a tester::CaseError. +/// +/// # Arguments +/// +/// * `error` - The ProgramLoadError to convert +/// +/// # Returns +/// +/// * `tester::CaseError` - The converted error +pub fn to_case_error_from_load(error: crate::mollusk::ProgramLoadError) -> tester::CaseError { + Box::new(error) as Box +} + +/// Convert a TestContextError to a tester::CaseError (for use with map_err). +/// +/// This is a helper function for converting errors in a map_err context. +/// +/// # Arguments +/// +/// * `error` - The TestContextError to convert +/// +/// # Returns +/// +/// * `tester::CaseError` - The converted error +#[allow(dead_code)] +pub fn to_case_error_from_context(error: TestContextError) -> tester::CaseError { + Box::new(error) as Box +} + +/// Check if a program is available for testing. +/// +/// # Arguments +/// +/// * `repo_dir` - The repository directory +/// +/// # Returns +/// +/// * `Ok(())` - If the program is available +/// * `Err(tester::CaseError)` - If the program is not available +pub fn check_program_available(repo_dir: &Path) -> Result<(), tester::CaseError> { + use crate::mollusk::load_lending_program; + + match load_lending_program(repo_dir) { + Ok(_) => Ok(()), + Err(e) => Err(Box::new(e) as Box), + } +} + +/// Create a test instruction for the lending program. +/// +/// # Arguments +/// +/// * `program_id` - The lending program ID +/// * `data` - The instruction data +/// * `accounts` - The accounts to pass to the instruction +/// +/// # Returns +/// +/// * `Instruction` - A lending program instruction +pub fn create_lending_instruction( + program_id: Pubkey, + data: Vec, + accounts: Vec, +) -> Instruction { + Instruction::new_with_bytes(program_id, &data, accounts) +} + +pub struct LendingFixture { + context: crate::mollusk::LendingTestContext, + program_id: Pubkey, + pub user: Pubkey, + #[allow(dead_code)] + pub token_program: Pubkey, + #[allow(dead_code)] + pub associated_token_program: Pubkey, +} + +impl LendingFixture { + pub fn new_default(repo_dir: &Path) -> Result { + let mut context = init_test_context(repo_dir)?; + let program_id = context.program_id(); + + let (system_program_id, system_program_account) = keyed_account_for_system_program(); + context.add_account(system_program_id, system_program_account); + + let (token_program_id, token_program_account) = token::keyed_account(); + context.add_account(token_program_id, token_program_account); + + let (associated_program_id, associated_program_account) = associated_token::keyed_account(); + context.add_account(associated_program_id, associated_program_account); + + let user = context.create_funded_account(1_000_000_000); + + Ok(Self { + context, + program_id, + user, + token_program: token_program_id, + associated_token_program: associated_program_id, + }) + } + + pub fn initialize_instruction(&self) -> Instruction { + let data = build_initialize_data(); + create_lending_instruction( + self.program_id, + data, + vec![ + AccountMeta::new(self.user, true), + AccountMeta::new_readonly(solana_system_program::id(), false), + ], + ) + } + + pub fn execute_initialize(&mut self) -> Result<(), TestContextError> { + let instruction = self.initialize_instruction(); + self.context.execute_instruction(&instruction) + } +} + +fn build_initialize_data() -> Vec { + anchor_discriminator("global:initialize").to_vec() +} + +fn anchor_discriminator(name: &str) -> [u8; 8] { + let mut hasher = Sha256::new(); + hasher.update(name.as_bytes()); + let hash = hasher.finalize(); + let mut out = [0u8; 8]; + out.copy_from_slice(&hash[..8]); + out +} + +pub fn run_env_setup_check() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + if !repo_path.exists() { + return Err(Box::new(std::io::Error::new( + std::io::ErrorKind::NotFound, + format!("Repository directory not found: {}", repo_path.display()), + )) as Box); + } + check_program_available(&repo_path)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_rust_basics_check() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_solana_model_check() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_anchor_try_check() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + let program_id = load_lending_program_id(&repo_path).map_err(to_case_error_from_load)?; + let default_id = Pubkey::from_str(DEFAULT_LENDING_PROGRAM_ID) + .map_err(|e| Box::new(e) as Box)?; + + if program_id == Pubkey::default() || program_id == default_id { + return Err(Box::new(std::io::Error::new( + std::io::ErrorKind::InvalidData, + "Program ID is still default", + )) as Box); + } + + run_initialize_smoke(&repo_path) +} + +pub fn run_spl_token_basics_check() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_cpi_transfer_check() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_token_transfer_check() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_pda_checks() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_treasury_checks() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_account_structure_checks() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_lending_core_checks() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_oracle_checks() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_liquidation_checks() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_interest_checks() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +pub fn run_security_checks() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +#[allow(dead_code)] +pub fn run_testing_checks() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + run_initialize_smoke(&repo_path) +} + +#[allow(dead_code)] +pub fn run_deployment_checks() -> Result<(), tester::CaseError> { + let repo_path = get_repo_dir().map_err(to_case_error_from_load)?; + let program_id = load_lending_program_id(&repo_path).map_err(to_case_error_from_load)?; + let default_id = Pubkey::from_str(DEFAULT_LENDING_PROGRAM_ID) + .map_err(|e| Box::new(e) as Box)?; + + if program_id == Pubkey::default() || program_id == default_id { + return Err(Box::new(std::io::Error::new( + std::io::ErrorKind::InvalidData, + "Program ID is still default", + )) as Box); + } + + run_initialize_smoke(&repo_path) +} + +fn run_initialize_smoke(repo_path: &Path) -> Result<(), tester::CaseError> { + let mut fixture = LendingFixture::new_default(repo_path).map_err(to_case_error)?; + match fixture.execute_initialize() { + Ok(()) => Ok(()), + Err(TestContextError::ExecutionError(_)) => Ok(()), + Err(err) => Err(to_case_error(err)), + } +} diff --git a/src/main.rs b/src/main.rs index c54390d..a19d442 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,6 +13,8 @@ // limitations under the License. mod definition; +mod helpers; +mod mollusk; mod stages; use std::process::ExitCode; diff --git a/src/mollusk/mod.rs b/src/mollusk/mod.rs new file mode 100644 index 0000000..3bb5b83 --- /dev/null +++ b/src/mollusk/mod.rs @@ -0,0 +1,107 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Mollusk management module for the lending program tester. +//! +//! This module provides a wrapper around the Mollusk test harness to simplify +//! testing of the lending program. It handles program loading, account setup, +//! and instruction execution. + +pub mod program_loader; +pub mod test_context; + +pub use program_loader::{ProgramLoadError, load_lending_program, load_lending_program_id}; +pub use test_context::{LendingTestContext, TestContextError}; + +use mollusk_svm::Mollusk; +use solana_pubkey::Pubkey; +use std::path::Path; + +/// The default program ID for the lending program. +/// This should match the program ID defined in the user's Anchor.toml. +#[allow(dead_code)] +pub const LENDING_PROGRAM_ID: Pubkey = Pubkey::new_from_array([ + 0x9a, 0x5e, 0x9e, 0x6a, 0x3c, 0x6b, 0x8e, 0x7d, 0x4a, 0x2f, 0x5b, 0x1c, 0x8d, 0x3e, 0x7f, 0x6a, + 0x2b, 0x8c, 0x1d, 0x4e, 0x5f, 0x6a, 0x7b, 0x8c, 0x9d, 0x0e, 0x1f, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, +]); + +/// Create a new Mollusk instance for testing the lending program. +/// +/// This function attempts to load the compiled lending program from the +/// user's repository directory and creates a Mollusk instance configured +/// for testing. +/// +/// # Arguments +/// +/// * `repo_dir` - Path to the user's repository directory +/// +/// # Returns +/// +/// * `Ok(Mollusk)` - A configured Mollusk instance +/// * `Err(ProgramLoadError)` - If the program cannot be loaded +pub fn create_lending_mollusk( + repo_dir: &Path, + program_id: &Pubkey, +) -> Result { + let program_path = load_lending_program(repo_dir)?; + let program_name = + program_path.file_stem().and_then(|stem| stem.to_str()).unwrap_or("lending_program"); + + let program_dir = program_path + .parent() + .ok_or_else(|| ProgramLoadError::ProgramDirNotFound(program_path.clone()))?; + + // SAFETY: set_var is process-global; we set it once before loading the ELF. + unsafe { + std::env::set_var("SBF_OUT_DIR", program_dir); + } + + let mut mollusk = Mollusk::new(program_id, program_name); + + // Add necessary programs for testing + add_required_programs(&mut mollusk); + + Ok(mollusk) +} + +/// Add required programs to the Mollusk instance. +/// +/// This includes system programs and SPL Token programs that are commonly +/// used in lending operations. +fn add_required_programs(mollusk: &mut Mollusk) { + // System program is already included by default in Mollusk + + // SPL Token program and Associated Token program - needed for token operations + mollusk_svm_programs_token::token::add_program(mollusk); + mollusk_svm_programs_token::associated_token::add_program(mollusk); +} + +/// Initialize a test context with the lending program. +/// +/// This is a convenience function that creates both a Mollusk instance and +/// a test context for easier testing. +/// +/// # Arguments +/// +/// * `repo_dir` - Path to the user's repository directory +/// +/// # Returns +/// +/// * `Ok(LendingTestContext)` - A configured test context +/// * `Err(TestContextError)` - If initialization fails +pub fn init_test_context(repo_dir: &Path) -> Result { + let program_id = load_lending_program_id(repo_dir)?; + let mollusk = create_lending_mollusk(repo_dir, &program_id)?; + LendingTestContext::new(mollusk, program_id) +} diff --git a/src/mollusk/program_loader.rs b/src/mollusk/program_loader.rs new file mode 100644 index 0000000..d48afd7 --- /dev/null +++ b/src/mollusk/program_loader.rs @@ -0,0 +1,276 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Program loader module for loading the lending program from disk. + +use mollusk_svm::file; +use solana_pubkey::Pubkey; +use std::{ + path::{Path, PathBuf}, + str::FromStr, +}; + +/// Error type for program loading operations. +#[derive(Debug)] +pub enum ProgramLoadError { + RepoNotFound(PathBuf), + AnchorTomlNotFound(PathBuf), + ProgramIdNotFound, + InvalidProgramId(String), + ProgramDirNotFound(PathBuf), + ProgramNotFound, + IoError(std::io::Error), + #[allow(dead_code)] + ElfLoadError(String), +} + +impl std::fmt::Display for ProgramLoadError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ProgramLoadError::RepoNotFound(path) => { + write!(f, "Repository directory not found: {}", path.display()) + } + ProgramLoadError::AnchorTomlNotFound(path) => { + write!(f, "Anchor.toml not found: {}", path.display()) + } + ProgramLoadError::ProgramIdNotFound => { + write!(f, "Program ID not found in Anchor.toml") + } + ProgramLoadError::InvalidProgramId(value) => { + write!(f, "Invalid program ID in Anchor.toml: {}", value) + } + ProgramLoadError::ProgramDirNotFound(path) => { + write!(f, "Program directory not found: {}", path.display()) + } + ProgramLoadError::ProgramNotFound => { + write!(f, "Program SO file not found in any of the expected locations") + } + ProgramLoadError::IoError(err) => write!(f, "Failed to read program file: {}", err), + ProgramLoadError::ElfLoadError(msg) => write!(f, "Failed to load program ELF: {}", msg), + } + } +} + +impl std::error::Error for ProgramLoadError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + ProgramLoadError::IoError(err) => Some(err), + _ => None, + } + } +} + +impl From for ProgramLoadError { + fn from(err: std::io::Error) -> Self { + ProgramLoadError::IoError(err) + } +} + +/// Load the lending program from the user's repository directory. +/// +/// This function searches for the compiled program SO file in the following +/// locations (in order): +/// +/// 1. `repo_dir/target/deploy/lending_program.so` +/// 2. `repo_dir/target/sbf-solana-solana/release/lending_program.so` +/// 3. `repo_dir/artifacts/lending_program.so` +/// +/// # Arguments +/// +/// * `repo_dir` - Path to the user's repository directory +/// +/// # Returns +/// +/// * `Ok(PathBuf)` - Path to the program SO file +/// * `Err(ProgramLoadError)` - If the program cannot be found or loaded +pub fn load_lending_program(repo_dir: &Path) -> Result { + if !repo_dir.exists() { + return Err(ProgramLoadError::RepoNotFound(repo_dir.to_path_buf())); + } + + // Try standard Anchor deployment path + let deploy_path = repo_dir.join("target/deploy/lending_program.so"); + if deploy_path.exists() { + return Ok(deploy_path); + } + + // Try SBF release path + let sbf_path = repo_dir.join("target/sbf-solana-solana/release/lending_program.so"); + if sbf_path.exists() { + return Ok(sbf_path); + } + + // Try artifacts directory + let artifacts_path = repo_dir.join("artifacts/lending_program.so"); + if artifacts_path.exists() { + return Ok(artifacts_path); + } + + // Try to find any .so file in the target directory + if let Some(so_file) = find_so_file_in_target(repo_dir) { + return Ok(so_file); + } + + Err(ProgramLoadError::ProgramNotFound) +} + +/// Load the lending program ID from Anchor.toml. +/// +/// This function attempts to parse the program ID from the `programs.*` +/// section in Anchor.toml. +/// +/// # Arguments +/// +/// * `repo_dir` - Path to the user's repository directory +/// +/// # Returns +/// +/// * `Ok(Pubkey)` - The program ID +/// * `Err(ProgramLoadError)` - If the program ID cannot be found or parsed +pub fn load_lending_program_id(repo_dir: &Path) -> Result { + if !repo_dir.exists() { + return Err(ProgramLoadError::RepoNotFound(repo_dir.to_path_buf())); + } + + let anchor_path = repo_dir.join("Anchor.toml"); + if !anchor_path.exists() { + return Err(ProgramLoadError::AnchorTomlNotFound(anchor_path)); + } + + let content = std::fs::read_to_string(&anchor_path)?; + let program_id = find_program_id(&content, "lending") + .or_else(|| find_program_id(&content, "lending_program")) + .or_else(|| find_first_program_id(&content)) + .ok_or(ProgramLoadError::ProgramIdNotFound)?; + + Pubkey::from_str(&program_id).map_err(|_| ProgramLoadError::InvalidProgramId(program_id)) +} + +fn find_program_id(toml: &str, program_name: &str) -> Option { + let mut in_programs_section = false; + + for raw_line in toml.lines() { + let line = raw_line.trim(); + + if line.starts_with('[') && line.ends_with(']') { + let section = &line[1..line.len() - 1]; + in_programs_section = section == "programs" || section.starts_with("programs."); + continue; + } + + if !in_programs_section || line.is_empty() || line.starts_with('#') { + continue; + } + + if let Some((key, value)) = line.split_once('=') && + key.trim() == program_name + { + let value = value.trim().trim_matches('"'); + if !value.is_empty() { + return Some(value.to_string()); + } + } + } + + None +} + +fn find_first_program_id(toml: &str) -> Option { + let mut in_programs_section = false; + + for raw_line in toml.lines() { + let line = raw_line.trim(); + + if line.starts_with('[') && line.ends_with(']') { + let section = &line[1..line.len() - 1]; + in_programs_section = section == "programs" || section.starts_with("programs."); + continue; + } + + if !in_programs_section || line.is_empty() || line.starts_with('#') { + continue; + } + + if let Some((_key, value)) = line.split_once('=') { + let value = value.trim().trim_matches('"'); + if !value.is_empty() { + return Some(value.to_string()); + } + } + } + + None +} + +/// Search for any .so file in the target directory. +fn find_so_file_in_target(repo_dir: &Path) -> Option { + let target_dir = repo_dir.join("target"); + if !target_dir.exists() { + return None; + } + + // Search recursively for .so files + let mut found = Vec::new(); + if let Ok(entries) = std::fs::read_dir(&target_dir) { + for entry in entries.flatten() { + let path = entry.path(); + if path.is_dir() { + if let Some(found_in_subdir) = find_so_file_recursive(&path) { + found.push(found_in_subdir); + } + } else if path.extension().is_some_and(|ext| ext == "so") { + found.push(path); + } + } + } + + // Return the first found .so file + found.into_iter().next() +} + +/// Recursively search for .so files in a directory. +fn find_so_file_recursive(dir: &Path) -> Option { + if let Ok(entries) = std::fs::read_dir(dir) { + for entry in entries.flatten() { + let path = entry.path(); + if path.is_dir() { + if let Some(found) = find_so_file_recursive(&path) { + return Some(found); + } + } else if path.extension().is_some_and(|ext| ext == "so") { + return Some(path); + } + } + } + None +} + +/// Load the program ELF bytes from a file path. +/// +/// This is a wrapper around Mollusk's file loading functionality that +/// provides better error messages. +/// +/// # Arguments +/// +/// * `path` - Path to the program SO file +/// +/// # Returns +/// +/// * `Ok(Vec)` - The program ELF bytes +/// * `Err(ProgramLoadError)` - If the file cannot be read +#[allow(dead_code)] +pub fn load_program_elf(path: &Path) -> Result, ProgramLoadError> { + let elf = file::load_program_elf(path.to_str().unwrap()); + Ok(elf) +} diff --git a/src/mollusk/test_context.rs b/src/mollusk/test_context.rs new file mode 100644 index 0000000..49db31a --- /dev/null +++ b/src/mollusk/test_context.rs @@ -0,0 +1,258 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Test context module for managing state during testing. + +use mollusk_svm::{ + Mollusk, + result::{Check, InstructionResult}, +}; +use solana_account::Account; +use solana_instruction::Instruction; +use solana_instruction_error::InstructionError; +use solana_pubkey::Pubkey; +use std::collections::HashMap; + +/// Error type for test context operations. +#[derive(Debug)] +pub enum TestContextError { + ExecutionError(String), + #[allow(dead_code)] + ValidationError(String), + #[allow(dead_code)] + AccountNotFound(String), +} + +impl std::fmt::Display for TestContextError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TestContextError::ExecutionError(msg) => { + write!(f, "Instruction execution failed: {}", msg) + } + TestContextError::ValidationError(msg) => write!(f, "Validation failed: {}", msg), + TestContextError::AccountNotFound(msg) => write!(f, "Account not found: {}", msg), + } + } +} + +impl std::error::Error for TestContextError {} + +impl From for TestContextError { + fn from(err: InstructionError) -> Self { + TestContextError::ExecutionError(format!("{:?}", err)) + } +} + +impl From for TestContextError { + fn from(err: crate::mollusk::ProgramLoadError) -> Self { + TestContextError::ExecutionError(err.to_string()) + } +} + +/// A test context for the lending program. +/// +/// This struct manages the state of accounts during testing and provides +/// convenience methods for executing and validating instructions. +pub struct LendingTestContext { + /// The Mollusk test harness. + mollusk: Mollusk, + /// The current state of accounts. + accounts: HashMap, + /// The program ID being tested. + program_id: Pubkey, +} + +impl LendingTestContext { + /// Create a new test context. + /// + /// # Arguments + /// + /// * `mollusk` - The Mollusk test harness + /// * `program_id` - The lending program ID + /// + /// # Returns + /// + /// * `Ok(LendingTestContext)` - A new test context + pub fn new(mollusk: Mollusk, program_id: Pubkey) -> Result { + Ok(Self { mollusk, accounts: HashMap::new(), program_id }) + } + + /// Get the program ID. + pub fn program_id(&self) -> Pubkey { + self.program_id + } + + /// Add an account to the test context. + /// + /// # Arguments + /// + /// * `pubkey` - The account's public key + /// * `account` - The account data + pub fn add_account(&mut self, pubkey: Pubkey, account: Account) { + self.accounts.insert(pubkey, account); + } + + /// Get an account from the test context. + /// + /// # Arguments + /// + /// * `pubkey` - The account's public key + /// + /// # Returns + /// + /// * `Some(Account)` - The account data if it exists + /// * `None` - If the account does not exist + #[allow(dead_code)] + pub fn get_account(&self, pubkey: &Pubkey) -> Option { + self.accounts.get(pubkey).cloned() + } + + /// Execute an instruction and update the account state. + /// + /// # Arguments + /// + /// * `instruction` - The instruction to execute + /// + /// # Returns + /// + /// * `Ok(())` - If the instruction executed successfully + /// * `Err(TestContextError)` - If execution failed + pub fn execute_instruction( + &mut self, + instruction: &Instruction, + ) -> Result<(), TestContextError> { + let result: InstructionResult = + self.mollusk.process_instruction(instruction, &self.get_account_list()); + + // Check if execution was successful + if result.program_result.is_err() { + return Err(TestContextError::ExecutionError(format!("{:?}", result.program_result))); + } + + // Update account state from the result + for (pubkey, account) in result.resulting_accounts { + self.accounts.insert(pubkey, account); + } + + Ok(()) + } + + /// Execute an instruction and validate the result. + /// + /// # Arguments + /// + /// * `instruction` - The instruction to execute + /// * `checks` - The checks to apply to the result + /// + /// # Returns + /// + /// * `Ok(())` - If the instruction executed and all checks passed + /// * `Err(TestContextError)` - If execution or validation failed + #[allow(dead_code)] + pub fn execute_and_validate( + &mut self, + instruction: &Instruction, + checks: &[Check], + ) -> Result<(), TestContextError> { + let result: InstructionResult = self.mollusk.process_and_validate_instruction( + instruction, + &self.get_account_list(), + checks, + ); + + // Check if execution was successful + if result.program_result.is_err() { + return Err(TestContextError::ExecutionError(format!("{:?}", result.program_result))); + } + + // Update account state from the result + for (pubkey, account) in result.resulting_accounts { + self.accounts.insert(pubkey, account); + } + + Ok(()) + } + + /// Get the current account list for Mollusk. + fn get_account_list(&self) -> Vec<(Pubkey, Account)> { + self.accounts.iter().map(|(pubkey, account)| (*pubkey, account.clone())).collect() + } + + /// Create a new keypair and add a funded account to the context. + /// + /// This is a convenience method for creating user accounts with + /// initial lamports. + /// + /// # Arguments + /// + /// * `lamports` - Initial lamports to fund the account with + /// + /// # Returns + /// + /// * `Pubkey` - The public key of the new account + pub fn create_funded_account(&mut self, lamports: u64) -> Pubkey { + let pubkey = Pubkey::new_unique(); + let account = + Account { lamports, owner: solana_system_program::id(), ..Default::default() }; + self.add_account(pubkey, account); + pubkey + } + + /// Create a token account. + /// + /// This is a convenience method for creating token accounts. + /// + /// # Arguments + /// + /// * `owner` - The owner of the token account + /// * `mint` - The mint address + /// * `amount` - Initial token amount + /// + /// # Returns + /// + /// * `Pubkey` - The public key of the new token account + #[allow(dead_code)] + pub fn create_token_account(&mut self, owner: Pubkey, mint: Pubkey, amount: u64) -> Pubkey { + let pubkey = Pubkey::new_unique(); + let mut data = vec![0; 82]; // Token account size + + // Set owner (offset 32) + data[32..64].copy_from_slice(owner.as_ref()); + + // Set mint (offset 0) + data[0..32].copy_from_slice(mint.as_ref()); + + // Set amount (offset 64, little-endian u64) + data[64..72].copy_from_slice(&amount.to_le_bytes()); + + let account = Account { + lamports: solana_rent::Rent::default().minimum_balance(data.len()), + data, + owner: spl_token_interface::ID, + ..Default::default() + }; + self.add_account(pubkey, account); + pubkey + } +} + +impl Default for LendingTestContext { + fn default() -> Self { + Self { + mollusk: Mollusk::default(), + accounts: HashMap::new(), + program_id: Pubkey::new_unique(), + } + } +} diff --git a/src/stages/base/at4.rs b/src/stages/base/at4.rs index 6599b80..8572f91 100644 --- a/src/stages/base/at4.rs +++ b/src/stages/base/at4.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_anchor_try(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_anchor_try_check() } diff --git a/src/stages/base/be1.rs b/src/stages/base/be1.rs index df9517e..f3cf406 100644 --- a/src/stages/base/be1.rs +++ b/src/stages/base/be1.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_env_setup(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_env_setup_check() } diff --git a/src/stages/base/cp6.rs b/src/stages/base/cp6.rs index 1469a46..d4b04eb 100644 --- a/src/stages/base/cp6.rs +++ b/src/stages/base/cp6.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_basic_deposit(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_cpi_transfer_check() } diff --git a/src/stages/base/rs2.rs b/src/stages/base/rs2.rs index c922fb8..d13d922 100644 --- a/src/stages/base/rs2.rs +++ b/src/stages/base/rs2.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_rust_basics(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_rust_basics_check() } diff --git a/src/stages/base/sm3.rs b/src/stages/base/sm3.rs index 7077f51..7c1d1d5 100644 --- a/src/stages/base/sm3.rs +++ b/src/stages/base/sm3.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_solana_model(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_solana_model_check() } diff --git a/src/stages/base/st5.rs b/src/stages/base/st5.rs index 9a2a2ad..cb02b42 100644 --- a/src/stages/base/st5.rs +++ b/src/stages/base/st5.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_spl_token_basics(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_spl_token_basics_check() } diff --git a/src/stages/base/tt7.rs b/src/stages/base/tt7.rs index 82bd48a..4b3f4cb 100644 --- a/src/stages/base/tt7.rs +++ b/src/stages/base/tt7.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_basic_withdraw(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_token_transfer_check() } diff --git a/src/stages/extensions/account_structure/as1.rs b/src/stages/extensions/account_structure/as1.rs index ff2e389..a3f3cb7 100644 --- a/src/stages/extensions/account_structure/as1.rs +++ b/src/stages/extensions/account_structure/as1.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_bank_account(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_account_structure_checks() } diff --git a/src/stages/extensions/account_structure/as2.rs b/src/stages/extensions/account_structure/as2.rs index f68edb8..2c496ed 100644 --- a/src/stages/extensions/account_structure/as2.rs +++ b/src/stages/extensions/account_structure/as2.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_user_account(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_account_structure_checks() } diff --git a/src/stages/extensions/account_structure/as3.rs b/src/stages/extensions/account_structure/as3.rs index b9254a4..7b9386c 100644 --- a/src/stages/extensions/account_structure/as3.rs +++ b/src/stages/extensions/account_structure/as3.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_account_space(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_account_structure_checks() } diff --git a/src/stages/extensions/account_structure/as4.rs b/src/stages/extensions/account_structure/as4.rs index b104091..f5904a9 100644 --- a/src/stages/extensions/account_structure/as4.rs +++ b/src/stages/extensions/account_structure/as4.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_account_practice(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_account_structure_checks() } diff --git a/src/stages/extensions/interest/in1.rs b/src/stages/extensions/interest/in1.rs index cfb0baf..38170cb 100644 --- a/src/stages/extensions/interest/in1.rs +++ b/src/stages/extensions/interest/in1.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_interest_basics(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_interest_checks() } diff --git a/src/stages/extensions/interest/in2.rs b/src/stages/extensions/interest/in2.rs index dddb4d6..fafb50a 100644 --- a/src/stages/extensions/interest/in2.rs +++ b/src/stages/extensions/interest/in2.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_accrued_interest(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_interest_checks() } diff --git a/src/stages/extensions/interest/in3.rs b/src/stages/extensions/interest/in3.rs index 05fb767..2823085 100644 --- a/src/stages/extensions/interest/in3.rs +++ b/src/stages/extensions/interest/in3.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_rate_models(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_interest_checks() } diff --git a/src/stages/extensions/interest/in4.rs b/src/stages/extensions/interest/in4.rs index b659036..ce6c170 100644 --- a/src/stages/extensions/interest/in4.rs +++ b/src/stages/extensions/interest/in4.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_interest_practice(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_interest_checks() } diff --git a/src/stages/extensions/lending_core/lc1.rs b/src/stages/extensions/lending_core/lc1.rs index 89b89f6..90023d4 100644 --- a/src/stages/extensions/lending_core/lc1.rs +++ b/src/stages/extensions/lending_core/lc1.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_borrow_basics(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_lending_core_checks() } diff --git a/src/stages/extensions/lending_core/lc2.rs b/src/stages/extensions/lending_core/lc2.rs index e5b4c75..e318fca 100644 --- a/src/stages/extensions/lending_core/lc2.rs +++ b/src/stages/extensions/lending_core/lc2.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_repay_basics(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_lending_core_checks() } diff --git a/src/stages/extensions/lending_core/lc3.rs b/src/stages/extensions/lending_core/lc3.rs index 7e6cc3c..2bdef59 100644 --- a/src/stages/extensions/lending_core/lc3.rs +++ b/src/stages/extensions/lending_core/lc3.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_ltv_calculation(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_lending_core_checks() } diff --git a/src/stages/extensions/lending_core/lc4.rs b/src/stages/extensions/lending_core/lc4.rs index d758f18..ba1858e 100644 --- a/src/stages/extensions/lending_core/lc4.rs +++ b/src/stages/extensions/lending_core/lc4.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_core_practice(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_lending_core_checks() } diff --git a/src/stages/extensions/liquidation/li1.rs b/src/stages/extensions/liquidation/li1.rs index a0654e7..d77879a 100644 --- a/src/stages/extensions/liquidation/li1.rs +++ b/src/stages/extensions/liquidation/li1.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_health_factor(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_liquidation_checks() } diff --git a/src/stages/extensions/liquidation/li2.rs b/src/stages/extensions/liquidation/li2.rs index ca1b0cd..10d8fb6 100644 --- a/src/stages/extensions/liquidation/li2.rs +++ b/src/stages/extensions/liquidation/li2.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_liquidation_trigger(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_liquidation_checks() } diff --git a/src/stages/extensions/liquidation/li3.rs b/src/stages/extensions/liquidation/li3.rs index 39517be..96fd88a 100644 --- a/src/stages/extensions/liquidation/li3.rs +++ b/src/stages/extensions/liquidation/li3.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_liquidation_process(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_liquidation_checks() } diff --git a/src/stages/extensions/liquidation/li4.rs b/src/stages/extensions/liquidation/li4.rs index dc59d03..e23c4a5 100644 --- a/src/stages/extensions/liquidation/li4.rs +++ b/src/stages/extensions/liquidation/li4.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_liquidation_bonus(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_liquidation_checks() } diff --git a/src/stages/extensions/liquidation/li5.rs b/src/stages/extensions/liquidation/li5.rs index 406e413..137ca48 100644 --- a/src/stages/extensions/liquidation/li5.rs +++ b/src/stages/extensions/liquidation/li5.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_liquidation_practice(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_liquidation_checks() } diff --git a/src/stages/extensions/oracle/or1.rs b/src/stages/extensions/oracle/or1.rs index 5d388f4..8df2762 100644 --- a/src/stages/extensions/oracle/or1.rs +++ b/src/stages/extensions/oracle/or1.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_oracle_concept(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_oracle_checks() } diff --git a/src/stages/extensions/oracle/or2.rs b/src/stages/extensions/oracle/or2.rs index def8deb..69f0952 100644 --- a/src/stages/extensions/oracle/or2.rs +++ b/src/stages/extensions/oracle/or2.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_pyth_integration(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_oracle_checks() } diff --git a/src/stages/extensions/oracle/or3.rs b/src/stages/extensions/oracle/or3.rs index c17905f..7d4f7fb 100644 --- a/src/stages/extensions/oracle/or3.rs +++ b/src/stages/extensions/oracle/or3.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_price_fetching(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_oracle_checks() } diff --git a/src/stages/extensions/oracle/or4.rs b/src/stages/extensions/oracle/or4.rs index 6829bab..9fbbc0c 100644 --- a/src/stages/extensions/oracle/or4.rs +++ b/src/stages/extensions/oracle/or4.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_oracle_practice(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_oracle_checks() } diff --git a/src/stages/extensions/pda/pa1.rs b/src/stages/extensions/pda/pa1.rs index 6689471..abfa5f6 100644 --- a/src/stages/extensions/pda/pa1.rs +++ b/src/stages/extensions/pda/pa1.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_pda_concept(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_pda_checks() } diff --git a/src/stages/extensions/pda/pa2.rs b/src/stages/extensions/pda/pa2.rs index 6106560..75fdb1e 100644 --- a/src/stages/extensions/pda/pa2.rs +++ b/src/stages/extensions/pda/pa2.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_pda_derivation(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_pda_checks() } diff --git a/src/stages/extensions/pda/pa3.rs b/src/stages/extensions/pda/pa3.rs index bf32367..222e251 100644 --- a/src/stages/extensions/pda/pa3.rs +++ b/src/stages/extensions/pda/pa3.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_pda_bump_seeds(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_pda_checks() } diff --git a/src/stages/extensions/pda/pa4.rs b/src/stages/extensions/pda/pa4.rs index 4ceda03..5f9dfce 100644 --- a/src/stages/extensions/pda/pa4.rs +++ b/src/stages/extensions/pda/pa4.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_pda_practice(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_pda_checks() } diff --git a/src/stages/extensions/security/se1.rs b/src/stages/extensions/security/se1.rs index d93d858..a3371ac 100644 --- a/src/stages/extensions/security/se1.rs +++ b/src/stages/extensions/security/se1.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_common_vulnerabilities(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_security_checks() } diff --git a/src/stages/extensions/security/se2.rs b/src/stages/extensions/security/se2.rs index 9abe8c5..9b133ae 100644 --- a/src/stages/extensions/security/se2.rs +++ b/src/stages/extensions/security/se2.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_reentrancy_protection(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_security_checks() } diff --git a/src/stages/extensions/security/se3.rs b/src/stages/extensions/security/se3.rs index df5f947..a9abb03 100644 --- a/src/stages/extensions/security/se3.rs +++ b/src/stages/extensions/security/se3.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_account_validation(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_security_checks() } diff --git a/src/stages/extensions/security/se4.rs b/src/stages/extensions/security/se4.rs index e490a49..415a4da 100644 --- a/src/stages/extensions/security/se4.rs +++ b/src/stages/extensions/security/se4.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_security_practice(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_security_checks() } diff --git a/src/stages/extensions/treasury/tr1.rs b/src/stages/extensions/treasury/tr1.rs index e9f6f5d..0be1076 100644 --- a/src/stages/extensions/treasury/tr1.rs +++ b/src/stages/extensions/treasury/tr1.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_treasury_intro(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_treasury_checks() } diff --git a/src/stages/extensions/treasury/tr2.rs b/src/stages/extensions/treasury/tr2.rs index 59811f1..43497cc 100644 --- a/src/stages/extensions/treasury/tr2.rs +++ b/src/stages/extensions/treasury/tr2.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_treasury_creation(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_treasury_checks() } diff --git a/src/stages/extensions/treasury/tr3.rs b/src/stages/extensions/treasury/tr3.rs index 55a2d47..41d831f 100644 --- a/src/stages/extensions/treasury/tr3.rs +++ b/src/stages/extensions/treasury/tr3.rs @@ -1,3 +1,17 @@ +// Copyright (c) The StackClass Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + pub fn test_treasury_security(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_treasury_checks() } diff --git a/src/stages/extensions/treasury/tr4.rs b/src/stages/extensions/treasury/tr4.rs index 64a7673..d34da43 100644 --- a/src/stages/extensions/treasury/tr4.rs +++ b/src/stages/extensions/treasury/tr4.rs @@ -13,5 +13,5 @@ // limitations under the License. pub fn test_treasury_practice(_harness: &tester::Harness) -> Result<(), tester::CaseError> { - Ok(()) + crate::helpers::run_treasury_checks() } From 61532418564ffd98fb88d4f2e8256c21f4c51405 Mon Sep 17 00:00:00 2001 From: lispking Date: Thu, 8 Jan 2026 12:08:04 +0800 Subject: [PATCH 2/4] fix: add missing source and checksum fields in Cargo.lock Add missing registry source and checksum entries for mollusk packages to resolve dependency resolution warnings. --- Cargo.lock | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 9301123..6fb6dd1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1210,6 +1210,8 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "mollusk-svm" version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57bd87f57490db674ffc141816c686785645f39c96cbd4416b76ed24f68e7ea3" dependencies = [ "agave-feature-set", "agave-syscalls", @@ -1252,6 +1254,8 @@ dependencies = [ [[package]] name = "mollusk-svm-error" version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70625b18d5a95041df7d218538da2520bc5a709a755db3885ff5e16baab1d408" dependencies = [ "solana-pubkey 4.0.0", "thiserror 1.0.69", @@ -1260,6 +1264,8 @@ dependencies = [ [[package]] name = "mollusk-svm-programs-token" version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "522e167efd4875c627928d126319bca254e5643366612dea9f42e4d0fe38bfc6" dependencies = [ "mollusk-svm", "solana-account", @@ -1273,6 +1279,8 @@ dependencies = [ [[package]] name = "mollusk-svm-result" version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7adc27e15c35ce197850ced1cce6ebbf15dac6e163c575198f68fc060a8c3814" dependencies = [ "solana-account", "solana-instruction", From 22f78c892394901a6a814b8f43dd90851d0bb71c Mon Sep 17 00:00:00 2001 From: lispking Date: Thu, 8 Jan 2026 16:52:41 +0800 Subject: [PATCH 3/4] refactor: move load_lending_program import to module level --- src/helpers.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index 6e6f426..221982b 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -16,7 +16,8 @@ #[allow(dead_code)] use crate::mollusk::{ - ProgramLoadError, TestContextError, init_test_context, load_lending_program_id, + ProgramLoadError, TestContextError, init_test_context, load_lending_program, + load_lending_program_id, }; use mollusk_svm::{program::keyed_account_for_system_program, result::Check}; use mollusk_svm_programs_token::{associated_token, token}; @@ -209,8 +210,6 @@ pub fn to_case_error_from_context(error: TestContextError) -> tester::CaseError /// * `Ok(())` - If the program is available /// * `Err(tester::CaseError)` - If the program is not available pub fn check_program_available(repo_dir: &Path) -> Result<(), tester::CaseError> { - use crate::mollusk::load_lending_program; - match load_lending_program(repo_dir) { Ok(_) => Ok(()), Err(e) => Err(Box::new(e) as Box), From fa594555bb0280b1d70f8b82738885833fc42d2b Mon Sep 17 00:00:00 2001 From: lispking Date: Thu, 8 Jan 2026 17:17:54 +0800 Subject: [PATCH 4/4] refactor: simplify program_id lookup in load_lending_program_id - Remove find_first_program_id fallback function - Only search for 'lending-program' program ID directly --- src/mollusk/program_loader.rs | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/src/mollusk/program_loader.rs b/src/mollusk/program_loader.rs index d48afd7..c047384 100644 --- a/src/mollusk/program_loader.rs +++ b/src/mollusk/program_loader.rs @@ -149,10 +149,8 @@ pub fn load_lending_program_id(repo_dir: &Path) -> Result Option { None } -fn find_first_program_id(toml: &str) -> Option { - let mut in_programs_section = false; - - for raw_line in toml.lines() { - let line = raw_line.trim(); - - if line.starts_with('[') && line.ends_with(']') { - let section = &line[1..line.len() - 1]; - in_programs_section = section == "programs" || section.starts_with("programs."); - continue; - } - - if !in_programs_section || line.is_empty() || line.starts_with('#') { - continue; - } - - if let Some((_key, value)) = line.split_once('=') { - let value = value.trim().trim_matches('"'); - if !value.is_empty() { - return Some(value.to_string()); - } - } - } - - None -} - /// Search for any .so file in the target directory. fn find_so_file_in_target(repo_dir: &Path) -> Option { let target_dir = repo_dir.join("target");