From 59113109ae6394ae51182e0170e02c63a4d85b21 Mon Sep 17 00:00:00 2001 From: mansur-codes Date: Wed, 27 May 2026 15:37:42 +0100 Subject: [PATCH 1/2] feat(adl_handler): complete execute_adl implementation. --- contracts/token/src/test.rs | 120 +++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/contracts/token/src/test.rs b/contracts/token/src/test.rs index 7d48a44..b202e70 100644 --- a/contracts/token/src/test.rs +++ b/contracts/token/src/test.rs @@ -3,7 +3,7 @@ use soroban_sdk::testutils::Address as _; use soroban_sdk::{vec, Address, Env, String, Vec}; -use crate::{BcForgeToken, BcForgeTokenClient, TokenError}; +use crate::{BcForgeToken, BcForgeTokenClient, Recipient, TokenError}; fn setup(env: &Env) -> (BcForgeTokenClient<'_>, Address) { let contract_id = env.register(BcForgeToken, ()); @@ -130,3 +130,121 @@ fn test_batch_transfer_while_paused_returns_error() { ))) ); } + +#[test] +fn test_batch_mint_single_recipient() { + let env = Env::default(); + env.mock_all_auths(); + let (client, _admin) = setup(&env); + let recipient = Address::generate(&env); + + let recipients = vec![ + &env, + Recipient { + address: recipient.clone(), + amount: 1000, + }, + ]; + + client.batch_mint(&recipients); + + assert_eq!(client.balance(&recipient), 1000); + assert_eq!(client.supply(), 1000); +} + +#[test] +fn test_batch_mint_multiple_recipients() { + let env = Env::default(); + env.mock_all_auths(); + let (client, _admin) = setup(&env); + let r1 = Address::generate(&env); + let r2 = Address::generate(&env); + let r3 = Address::generate(&env); + + let recipients = vec![ + &env, + Recipient { + address: r1.clone(), + amount: 100, + }, + Recipient { + address: r2.clone(), + amount: 200, + }, + Recipient { + address: r3.clone(), + amount: 300, + }, + ]; + + client.batch_mint(&recipients); + + assert_eq!(client.balance(&r1), 100); + assert_eq!(client.balance(&r2), 200); + assert_eq!(client.balance(&r3), 300); + assert_eq!(client.supply(), 600); +} + +#[test] +fn test_batch_mint_rejects_invalid_amount() { + let env = Env::default(); + env.mock_all_auths(); + let (client, _admin) = setup(&env); + let r1 = Address::generate(&env); + let r2 = Address::generate(&env); + + let recipients = vec![ + &env, + Recipient { + address: r1.clone(), + amount: 100, + }, + Recipient { + address: r2.clone(), + amount: 0, // Zero amount + }, + ]; + + let res = client.try_batch_mint(&recipients); + assert_eq!( + res, + Err(Ok(soroban_sdk::Error::from_contract_error( + TokenError::InvalidAmount as u32 + ))) + ); + + // Verify atomic rollback (no tokens minted) + assert_eq!(client.balance(&r1), 0); + assert_eq!(client.balance(&r2), 0); + assert_eq!(client.supply(), 0); +} + +#[test] +fn test_batch_mint_while_paused_fails() { + let env = Env::default(); + env.mock_all_auths(); + let (client, _admin) = setup(&env); + let recipient = Address::generate(&env); + + let recipients = vec![ + &env, + Recipient { + address: recipient.clone(), + amount: 100, + }, + ]; + + client.pause(); + + let res = client.try_batch_mint(&recipients); + assert_eq!( + res, + Err(Ok(soroban_sdk::Error::from_contract_error( + TokenError::ContractPaused as u32 + ))) + ); + + // Verify no tokens minted + assert_eq!(client.balance(&recipient), 0); + assert_eq!(client.supply(), 0); +} From 35806b086d5d1b810707aafb772ed1c49a8475cb Mon Sep 17 00:00:00 2001 From: mansur-codes Date: Tue, 2 Jun 2026 07:01:22 +0100 Subject: [PATCH 2/2] feat(token): re-implement batch_mint function and fix workspace compilation #51 --- Cargo.lock | 2471 +++++++++++++++++++++++ contracts/admin/src/lib.rs | 6 +- contracts/lifecycle/src/lib.rs | 6 +- contracts/rate-limit/src/lib.rs | 58 +- contracts/token/src/lib.rs | 208 +- contracts/token/src/rate_limit.rs | 11 +- contracts/token/src/reentrancy_guard.rs | 14 +- contracts/token/src/test.rs | 12 +- contracts/vesting/Cargo.toml | 4 +- contracts/wrapper/Cargo.toml | 4 +- contracts/wrapper/src/lib.rs | 9 +- e2e/integration_test.rs | 6 +- 12 files changed, 2658 insertions(+), 151 deletions(-) create mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..6450c85 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2471 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "ark-bls12-381" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df4dcc01ff89867cd86b0da835f23c3f02738353aaee7dde7495af71363b8d5" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-bn254" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" +dependencies = [ + "ahash", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "educe", + "fnv", + "hashbrown 0.15.5", + "itertools", + "num-bigint", + "num-integer", + "num-traits", + "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", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "arrayvec", + "digest", + "educe", + "itertools", + "num-bigint", + "num-traits", + "paste", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ark-poly" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" +dependencies = [ + "ahash", + "ark-ff", + "ark-serialize", + "ark-std", + "educe", + "fnv", + "hashbrown 0.15.5", +] + +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "arrayvec", + "digest", + "num-bigint", +] + +[[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", +] + +[[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.6", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + +[[package]] +name = "bc-forge-admin" +version = "0.1.0" +dependencies = [ + "bc-forge-ttl", + "soroban-sdk", +] + +[[package]] +name = "bc-forge-e2e-tests" +version = "0.1.0" +dependencies = [ + "bc-forge-token", + "soroban-sdk", + "tokio", +] + +[[package]] +name = "bc-forge-lifecycle" +version = "0.1.0" +dependencies = [ + "bc-forge-ttl", + "soroban-sdk", +] + +[[package]] +name = "bc-forge-rate-limit" +version = "0.1.0" +dependencies = [ + "soroban-sdk", +] + +[[package]] +name = "bc-forge-token" +version = "0.1.0" +dependencies = [ + "bc-forge-admin", + "bc-forge-lifecycle", + "bc-forge-rate-limit", + "bc-forge-ttl", + "proptest", + "soroban-sdk", +] + +[[package]] +name = "bc-forge-ttl" +version = "0.1.0" +dependencies = [ + "soroban-sdk", +] + +[[package]] +name = "bc-forge-vesting" +version = "0.1.0" +dependencies = [ + "bc-forge-admin", + "bc-forge-token", + "soroban-sdk", +] + +[[package]] +name = "bc-forge-wrapper" +version = "0.1.0" +dependencies = [ + "bc-forge-admin", + "bc-forge-lifecycle", + "soroban-sdk", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" + +[[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 = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "bytes-lit" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0adabf37211a5276e46335feabcbb1530c95eb3fdf85f324c7db942770aa025d" +dependencies = [ + "num-bigint", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cc" +version = "1.2.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" +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_eval" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "chrono" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crate-git-revision" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c521bf1f43d31ed2f73441775ed31935d77901cb3451e44b38a1c1612fcbaf98" +dependencies = [ + "serde", + "serde_derive", + "serde_json", +] + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctor" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67773048316103656a637612c4a62477603b777d91d9c62ff2290f9cde178fdb" +dependencies = [ + "ctor-proc-macro", + "dtor", +] + +[[package]] +name = "ctor-proc-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" + +[[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", + "fiat-crypto", + "rustc_version", + "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", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", + "quote", + "syn", +] + +[[package]] +name = "data-encoding" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" + +[[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 = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dtor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301" +dependencies = [ + "dtor-proc-macro", +] + +[[package]] +name = "dtor-proc-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[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", +] + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[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", + "ff", + "generic-array", + "group", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[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", +] + +[[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 = "escape-bytes" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bfcf67fea2815c2fc3b90873fae90957be12ff417335dfadc7f52927feb03b2" + +[[package]] +name = "ethnum" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40404c3f5f511ec4da6fe866ddf6a717c309fdbb69fbbad7b0f3edab8f2e835f" + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[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 5.3.0", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + +[[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.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "indexmap-nostd" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" + +[[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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +dependencies = [ + "cfg-if", + "futures-util", + "once_cell", + "wasm-bindgen", +] + +[[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", + "sha2", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[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.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" + +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "memchr" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "mio" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[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-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[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", +] + +[[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-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[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 = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags", + "num-traits", + "rand 0.9.4", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +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 = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rand" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[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_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[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_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[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", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[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_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", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_with" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" +dependencies = [ + "base64", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.0", + "schemars 0.8.22", + "schemars 0.9.0", + "schemars 1.2.1", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" +dependencies = [ + "darling 0.23.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[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", + "rand_core 0.6.4", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "soroban-builtin-sdk-macros" +version = "26.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a3a2b57b132b800e132d2c81e1818359bb2cf787ca39c61c151d6bd0798403" +dependencies = [ + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "soroban-env-common" +version = "26.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c76fad735f9622d8aa0fa0c75838d2023a659a0c57638a783b8b2eb967f7822" +dependencies = [ + "arbitrary", + "crate-git-revision", + "ethnum", + "num-derive", + "num-traits", + "serde", + "soroban-env-macros", + "soroban-wasmi", + "static_assertions", + "stellar-xdr", + "wasmparser 0.116.1", +] + +[[package]] +name = "soroban-env-guest" +version = "26.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15aeed6d7a4dc4d3bba65e2ac92f7eeaa664900bbc82e1055e024bf637d74ed3" +dependencies = [ + "soroban-env-common", + "static_assertions", +] + +[[package]] +name = "soroban-env-host" +version = "26.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb523456b4efe9cdf869233cff5a2a1a5ebfae8c0acc405e57479c83781a20c" +dependencies = [ + "ark-bls12-381", + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "curve25519-dalek", + "ecdsa", + "ed25519-dalek", + "elliptic-curve", + "generic-array", + "getrandom 0.2.17", + "hex-literal", + "hmac", + "k256", + "num-derive", + "num-integer", + "num-traits", + "p256", + "rand 0.8.6", + "rand_chacha 0.3.1", + "sec1", + "sha2", + "sha3", + "soroban-builtin-sdk-macros", + "soroban-env-common", + "soroban-wasmi", + "static_assertions", + "stellar-strkey 0.0.13", + "wasmparser 0.116.1", +] + +[[package]] +name = "soroban-env-macros" +version = "26.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ada3449bb23c964a88a1bf633ac66ca3ebac2061693f53148b199ce816791d0" +dependencies = [ + "itertools", + "proc-macro2", + "quote", + "serde", + "serde_json", + "stellar-xdr", + "syn", +] + +[[package]] +name = "soroban-ledger-snapshot" +version = "26.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "231ae1585d14b5059adde392ce80f6b151e0264ed62b121bca9fe025e8ace460" +dependencies = [ + "serde", + "serde_json", + "serde_with", + "soroban-env-common", + "soroban-env-host", + "thiserror", +] + +[[package]] +name = "soroban-sdk" +version = "26.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de6ad39b7070e8703d01c3abad13e75ea5e65b1a5ce5e86b98d724773282044" +dependencies = [ + "arbitrary", + "bytes-lit", + "crate-git-revision", + "ctor", + "derive_arbitrary", + "ed25519-dalek", + "rand 0.8.6", + "rustc_version", + "serde", + "serde_json", + "soroban-env-guest", + "soroban-env-host", + "soroban-ledger-snapshot", + "soroban-sdk-macros", + "stellar-strkey 0.0.16", + "visibility", +] + +[[package]] +name = "soroban-sdk-macros" +version = "26.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72cd5e180920e224d209562cccffd27c35884d14c4dc296b295dfcebef46b6f1" +dependencies = [ + "darling 0.20.11", + "heck", + "itertools", + "macro-string", + "proc-macro2", + "quote", + "sha2", + "soroban-env-common", + "soroban-spec", + "soroban-spec-rust", + "stellar-xdr", + "syn", +] + +[[package]] +name = "soroban-spec" +version = "26.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680c70a2ab6d7cde343e9a51dd141f2f4304a7282452df8dc540b9bf62565886" +dependencies = [ + "base64", + "sha2", + "stellar-xdr", + "thiserror", + "wasmparser 0.116.1", +] + +[[package]] +name = "soroban-spec-rust" +version = "26.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e368f91c6633c25cd2d143fd82f84206b8e58718fc630d344f2fa33e6d31b1b" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "sha2", + "soroban-spec", + "stellar-xdr", + "syn", + "thiserror", +] + +[[package]] +name = "soroban-wasmi" +version = "0.31.1-soroban.20.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710403de32d0e0c35375518cb995d4fc056d0d48966f2e56ea471b8cb8fc9719" +dependencies = [ + "smallvec", + "spin", + "wasmi_arena", + "wasmi_core", + "wasmparser-nostd", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stellar-strkey" +version = "0.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee1832fb50c651ad10f734aaf5d31ca5acdfb197a6ecda64d93fcdb8885af913" +dependencies = [ + "crate-git-revision", + "data-encoding", +] + +[[package]] +name = "stellar-strkey" +version = "0.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "084afcb0d458c3d5d5baa2d294b18f881e62cc258ef539d8fdf68be7dbe45520" +dependencies = [ + "crate-git-revision", + "data-encoding", + "heapless", +] + +[[package]] +name = "stellar-xdr" +version = "26.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6e29c7e1f071c2767916460d006668197843d5d93f0ec8893a26f72a14f595" +dependencies = [ + "arbitrary", + "base64", + "cfg_eval", + "crate-git-revision", + "escape-bytes", + "ethnum", + "hex", + "serde", + "serde_with", + "sha2", + "stellar-strkey 0.0.13", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.2", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "time-macros" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +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 = "tokio" +version = "1.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "visibility" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + +[[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.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser 0.244.0", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.14.0", + "wasm-encoder", + "wasmparser 0.244.0", +] + +[[package]] +name = "wasmi_arena" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "104a7f73be44570cac297b3035d76b169d6599637631cf37a1703326a0727073" + +[[package]] +name = "wasmi_core" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf1a7db34bff95b85c261002720c00c3a6168256dcb93041d3fa2054d19856a" +dependencies = [ + "downcast-rs", + "libm", + "num-traits", + "paste", +] + +[[package]] +name = "wasmparser" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" +dependencies = [ + "indexmap 2.14.0", + "semver", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap 2.14.0", + "semver", +] + +[[package]] +name = "wasmparser-nostd" +version = "0.100.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5a015fe95f3504a94bb1462c717aae75253e39b9dd6c3fb1062c934535c64aa" +dependencies = [ + "indexmap-nostd", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[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 = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap 2.14.0", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap 2.14.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser 0.244.0", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.14.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser 0.244.0", +] + +[[package]] +name = "zerocopy" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/contracts/admin/src/lib.rs b/contracts/admin/src/lib.rs index e9b0fac..714f193 100644 --- a/contracts/admin/src/lib.rs +++ b/contracts/admin/src/lib.rs @@ -232,7 +232,7 @@ pub fn mark_executed(env: &Env, proposal_id: u64) { #[cfg(test)] mod tests { use super::*; - use soroban_sdk::testutils::Address as _; + use soroban_sdk::testutils::{Address as _, Ledger as _}; use soroban_sdk::{contract, contractimpl, Address, Env}; #[contract] @@ -265,7 +265,9 @@ mod tests { client.set_admin(&admin); client.grant_role(&Role::Minter, &role_holder); - env.ledger().set(env.ledger().sequence() + 200); + let mut info = env.ledger().get(); + info.sequence_number += 200; + env.ledger().set(info); assert!(client.has_role(&Role::Minter, &role_holder)); } } diff --git a/contracts/lifecycle/src/lib.rs b/contracts/lifecycle/src/lib.rs index 9144464..3f5810b 100644 --- a/contracts/lifecycle/src/lib.rs +++ b/contracts/lifecycle/src/lib.rs @@ -83,7 +83,7 @@ pub fn require_not_paused(env: &Env) { #[cfg(test)] mod tests { use super::*; - use soroban_sdk::testutils::Address as _; + use soroban_sdk::testutils::{Address as _, Ledger as _}; use soroban_sdk::Env; use soroban_sdk::{contract, contractimpl}; @@ -177,7 +177,9 @@ mod tests { let admin = Address::generate(&env); client.pause(&admin); - env.ledger().set(env.ledger().sequence() + 200); + let mut info = env.ledger().get(); + info.sequence_number += 200; + env.ledger().set(info); assert!(client.is_paused()); }} diff --git a/contracts/rate-limit/src/lib.rs b/contracts/rate-limit/src/lib.rs index 2cff2e3..da5a322 100644 --- a/contracts/rate-limit/src/lib.rs +++ b/contracts/rate-limit/src/lib.rs @@ -5,7 +5,7 @@ #![no_std] -use soroban_sdk::{contract, contractimpl, contracttype, Address, Env, Vec}; +use soroban_sdk::{contract, contractimpl, contracttype, Address, Env, String}; #[derive(Clone)] #[contracttype] @@ -46,32 +46,32 @@ impl BcForgeRateLimit { env.ledger().timestamp() } - fn get_global_config(env: &Env, operation_type: &str) -> Option { + fn get_global_config(env: &Env, operation_type: String) -> Option { env.storage() .instance() - .get::<_, RateLimitConfig>(&DataKey::GlobalRateLimit(operation_type.to_string())) + .get::<_, RateLimitConfig>(&DataKey::GlobalRateLimit(operation_type)) } - fn get_address_config(env: &Env, address: &Address, operation_type: &str) -> Option { + fn get_address_config(env: &Env, address: &Address, operation_type: String) -> Option { env.storage() .instance() - .get::<_, RateLimitConfig>(&DataKey::AddressRateLimit(address.clone(), operation_type.to_string())) + .get::<_, RateLimitConfig>(&DataKey::AddressRateLimit(address.clone(), operation_type)) } - fn get_global_state(env: &Env, operation_type: &str) -> RateLimitState { + fn get_global_state(env: &Env, operation_type: String) -> RateLimitState { env.storage() .instance() - .get::<_, RateLimitState>(&DataKey::GlobalCount(operation_type.to_string())) + .get::<_, RateLimitState>(&DataKey::GlobalCount(operation_type)) .unwrap_or(RateLimitState { count: 0, last_reset: 0, }) } - fn get_address_state(env: &Env, address: &Address, operation_type: &str) -> RateLimitState { + fn get_address_state(env: &Env, address: &Address, operation_type: String) -> RateLimitState { env.storage() .instance() - .get::<_, RateLimitState>(&DataKey::AddressCount(address.clone(), operation_type.to_string())) + .get::<_, RateLimitState>(&DataKey::AddressCount(address.clone(), operation_type)) .unwrap_or(RateLimitState { count: 0, last_reset: 0, @@ -93,24 +93,24 @@ impl BcForgeRateLimit { /// Check if the operation is allowed based on rate limits /// Returns true if allowed, false if rate limited - pub fn check_rate_limit( + pub fn check_rate_limit_lib( env: &Env, address: Option<&Address>, - operation_type: &str, - amount: u64, + operation_type: String, + _amount: u64, ) -> bool { let current_time = Self::get_current_timestamp(env); // Check global rate limit first - if let Some(global_config) = Self::get_global_config(env, operation_type) { - let mut global_state = Self::get_global_state(env, operation_type); + if let Some(global_config) = Self::get_global_config(env, operation_type.clone()) { + let mut global_state = Self::get_global_state(env, operation_type.clone()); Self::reset_if_needed( env, current_time, &global_config, &mut global_state, - &DataKey::GlobalCount(operation_type.to_string()), + &DataKey::GlobalCount(operation_type.clone()), ); if global_state.count >= global_config.limit { @@ -120,21 +120,21 @@ impl BcForgeRateLimit { Self::increment_count( env, &mut global_state, - &DataKey::GlobalCount(operation_type.to_string()), + &DataKey::GlobalCount(operation_type.clone()), ); } // Check per-address rate limit if address is provided if let Some(addr) = address { - if let Some(address_config) = Self::get_address_config(env, addr, operation_type) { - let mut address_state = Self::get_address_state(env, addr, operation_type); + if let Some(address_config) = Self::get_address_config(env, addr, operation_type.clone()) { + let mut address_state = Self::get_address_state(env, addr, operation_type.clone()); Self::reset_if_needed( env, current_time, &address_config, &mut address_state, - &DataKey::AddressCount(addr.clone(), operation_type.to_string()), + &DataKey::AddressCount(addr.clone(), operation_type.clone()), ); if address_state.count >= address_config.limit { @@ -144,7 +144,7 @@ impl BcForgeRateLimit { Self::increment_count( env, &mut address_state, - &DataKey::AddressCount(addr.clone(), operation_type.to_string()), + &DataKey::AddressCount(addr.clone(), operation_type.clone()), ); } } @@ -153,9 +153,9 @@ impl BcForgeRateLimit { } /// Set global rate limit for an operation type - pub fn set_global_rate_limit( + pub fn set_global_rate_limit_lib( env: &Env, - operation_type: &str, + operation_type: String, limit: u64, window_seconds: u64, ) { @@ -165,14 +165,14 @@ impl BcForgeRateLimit { }; env.storage() .instance() - .set(&DataKey::GlobalRateLimit(operation_type.to_string()), &config); + .set(&DataKey::GlobalRateLimit(operation_type), &config); } /// Set per-address rate limit for an operation type - pub fn set_address_rate_limit( + pub fn set_address_rate_limit_lib( env: &Env, address: &Address, - operation_type: &str, + operation_type: String, limit: u64, window_seconds: u64, ) { @@ -182,7 +182,7 @@ impl BcForgeRateLimit { }; env.storage() .instance() - .set(&DataKey::AddressRateLimit(address.clone(), operation_type.to_string()), &config); + .set(&DataKey::AddressRateLimit(address.clone(), operation_type), &config); } } @@ -197,7 +197,7 @@ impl BcForgeRateLimit { amount: u64, ) -> bool { let address_ref = address.as_ref(); - BcForgeRateLimit::check_rate_limit(&env, address_ref, &operation_type, amount) + BcForgeRateLimit::check_rate_limit_lib(&env, address_ref, operation_type, amount) } /// Set global rate limit for an operation type @@ -207,7 +207,7 @@ impl BcForgeRateLimit { limit: u64, window_seconds: u64, ) { - BcForgeRateLimit::set_global_rate_limit(&env, &operation_type, limit, window_seconds) + BcForgeRateLimit::set_global_rate_limit_lib(&env, operation_type, limit, window_seconds) } /// Set per-address rate limit for an operation type @@ -218,6 +218,6 @@ impl BcForgeRateLimit { limit: u64, window_seconds: u64, ) { - BcForgeRateLimit::set_address_rate_limit(&env, &address, &operation_type, limit, window_seconds) + BcForgeRateLimit::set_address_rate_limit_lib(&env, &address, operation_type, limit, window_seconds) } } diff --git a/contracts/token/src/lib.rs b/contracts/token/src/lib.rs index da0902d..430bb57 100644 --- a/contracts/token/src/lib.rs +++ b/contracts/token/src/lib.rs @@ -12,13 +12,21 @@ mod rate_limit; mod test; use bc_forge_admin as admin; +use bc_forge_ttl as ttl; use soroban_sdk::token::TokenInterface; use soroban_sdk::{ - contract, contracterror, contractimpl, contracttype, Address, Env, String, + contract, contracterror, contractimpl, contracttype, Address, Env, String, Vec, MuxedAddress, }; use reentrancy_guard::ReentrancyGuard; use rate_limit::BcForgeRateLimit; +#[derive(Clone, Debug, Eq, PartialEq)] +#[contracttype] +pub struct Recipient { + pub address: Address, + pub amount: i128, +} + #[derive(Clone)] #[contracttype] enum DataKey { @@ -160,6 +168,10 @@ impl BcForgeToken { events::emit_mint(env, admin_address, to, amount, new_balance, new_supply); Ok(()) } + + fn extend_instance_ttl_for_call(env: &Env) { + ttl::extend_instance_ttl(env); + } } #[contractimpl] @@ -193,7 +205,7 @@ impl BcForgeToken { reentrancy_guard!(&env, "mint_guard", { Self::ensure_initialized(&env)?; Self::ensure_not_paused(&env)?; - let current_admin = Self::read_admin(&env)?; + let current_admin = admin::get_admin(&env); current_admin.require_auth(); // Check rate limits for mint operation @@ -209,21 +221,32 @@ impl BcForgeToken { reentrancy_guard!(&env, "batch_mint_guard", { Self::ensure_initialized(&env)?; Self::ensure_not_paused(&env)?; - let current_admin = Self::read_admin(&env)?; + let current_admin = admin::get_admin(&env); current_admin.require_auth(); + Self::extend_instance_ttl_for_call(&env); + + let mut total_amount: i128 = 0; for i in 0..recipients.len() { let recipient = recipients.get(i).expect("recipient should exist"); if recipient.amount <= 0 { return Err(TokenError::InvalidAmount); } + total_amount = total_amount.checked_add(recipient.amount).ok_or(TokenError::InvalidAmount)?; } - Self::extend_instance_ttl_for_call(&env); - Self::ensure_initialized(&env)?; - Self::ensure_not_paused(&env)?; - let admin_address = admin::get_admin(&env); - admin_address.require_auth(); - Self::internal_mint(&env, &admin_address, &to, amount) + + // Check rate limits for batch mint operation (using total amount on the admin) + if !crate::rate_limit::check_mint_rate_limit(&env, ¤t_admin, total_amount) { + return Err(TokenError::InvalidAmount); + } + + for i in 0..recipients.len() { + let recipient = recipients.get(i).expect("recipient should exist"); + Self::internal_mint(&env, ¤t_admin, &recipient.address, recipient.amount)?; + } + + Ok(()) + }) } pub fn supply(env: Env) -> i128 { @@ -256,6 +279,10 @@ impl BcForgeToken { events::emit_unpaused(&env, &admin_address); Ok(()) } + + pub fn version(env: Env) -> String { + String::from_str(&env, "1.1.0") + } } #[contractimpl] @@ -268,22 +295,15 @@ impl TokenInterface for BcForgeToken { fn approve(env: Env, from: Address, spender: Address, amount: i128, exp: u32) { reentrancy_guard!(&env, "approve_guard", { + Self::extend_instance_ttl_for_call(&env); Self::panic_on_err(&env, Self::ensure_initialized(&env)); from.require_auth(); if amount < 0 { soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); } Self::write_allowance(&env, &from, &spender, amount, exp); - events::emit_approve(&env, &from, &spender, amount); + events::emit_approve(&env, &from, &spender, amount, exp); }) - Self::extend_instance_ttl_for_call(&env); - Self::panic_on_err(&env, Self::ensure_initialized(&env)); - from.require_auth(); - if amount < 0 { - soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); - } - Self::write_allowance(&env, &from, &spender, amount, exp); - events::emit_approve(&env, &from, &spender, amount, exp); } fn balance(env: Env, id: Address) -> i128 { @@ -292,101 +312,111 @@ impl TokenInterface for BcForgeToken { Self::read_balance(&env, &id) } - fn transfer(env: Env, from: Address, to: Address, amount: i128) { + fn transfer(env: Env, from: Address, to: MuxedAddress, amount: i128) { reentrancy_guard!(&env, "transfer_guard", { + Self::extend_instance_ttl_for_call(&env); Self::panic_on_err(&env, Self::ensure_initialized(&env)); Self::panic_on_err(&env, Self::ensure_not_paused(&env)); from.require_auth(); - Self::extend_instance_ttl_for_call(&env); - Self::panic_on_err(&env, Self::ensure_initialized(&env)); - Self::panic_on_err(&env, Self::ensure_not_paused(&env)); - from.require_auth(); - if amount <= 0 { - soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); - } - Self::panic_on_err(&env, Self::move_balance(&env, &from, &to, amount)); - events::emit_transfer(&env, &from, &to, amount); + if amount <= 0 { + soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); + } + let to_addr = to.address(); + Self::panic_on_err(&env, Self::move_balance(&env, &from, &to_addr, amount)); + events::emit_transfer(&env, &from, &to_addr, amount); + }) } fn transfer_from(env: Env, spender: Address, from: Address, to: Address, amount: i128) { - Self::extend_instance_ttl_for_call(&env); - Self::panic_on_err(&env, Self::ensure_initialized(&env)); - Self::panic_on_err(&env, Self::ensure_not_paused(&env)); - spender.require_auth(); - if amount <= 0 { - soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); - } + reentrancy_guard!(&env, "transfer_from_guard", { + Self::extend_instance_ttl_for_call(&env); + Self::panic_on_err(&env, Self::ensure_initialized(&env)); + Self::panic_on_err(&env, Self::ensure_not_paused(&env)); + spender.require_auth(); + if amount <= 0 { + soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); + } - let allowance = Self::allowance_amount(&env, &from, &spender); - if allowance < amount { - soroban_sdk::panic_with_error!(&env, TokenError::InsufficientAllowance); - } + let allowance = Self::allowance_amount(&env, &from, &spender); + if allowance < amount { + soroban_sdk::panic_with_error!(&env, TokenError::InsufficientAllowance); + } - let allowance_data = Self::read_allowance_data(&env, &from, &spender); - Self::panic_on_err(&env, Self::move_balance(&env, &from, &to, amount)); - Self::write_allowance( - &env, - &from, - &spender, - allowance - amount, - allowance_data.expiration_ledger, - ); - events::emit_transfer_from(&env, &spender, &from, &to, amount, allowance - amount); + let allowance_data = Self::read_allowance_data(&env, &from, &spender); + Self::panic_on_err(&env, Self::move_balance(&env, &from, &to, amount)); + Self::write_allowance( + &env, + &from, + &spender, + allowance - amount, + allowance_data.expiration_ledger, + ); + events::emit_transfer_from(&env, &spender, &from, &to, amount, allowance - amount); + }) } fn burn(env: Env, from: Address, amount: i128) { - Self::extend_instance_ttl_for_call(&env); - Self::panic_on_err(&env, Self::ensure_initialized(&env)); - Self::panic_on_err(&env, Self::ensure_not_paused(&env)); - from.require_auth(); - if amount <= 0 { - soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); - } + reentrancy_guard!(&env, "burn_guard", { + Self::extend_instance_ttl_for_call(&env); + Self::panic_on_err(&env, Self::ensure_initialized(&env)); + Self::panic_on_err(&env, Self::ensure_not_paused(&env)); + from.require_auth(); + if amount <= 0 { + soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); + } // Check rate limits for burn operation if !crate::rate_limit::check_burn_rate_limit(&env, &from, amount) { soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); } - let new_balance = balance - amount; - let new_supply = Self::read_supply(&env) - amount; - Self::write_balance(&env, &from, new_balance); - Self::write_supply(&env, new_supply); - events::emit_burn(&env, &from, amount, new_balance, new_supply); + let balance = Self::read_balance(&env, &from); + if balance < amount { + soroban_sdk::panic_with_error!(&env, TokenError::InsufficientBalance); + } + + let new_balance = balance - amount; + let new_supply = Self::read_supply(&env) - amount; + Self::write_balance(&env, &from, new_balance); + Self::write_supply(&env, new_supply); + events::emit_burn(&env, &from, amount, new_balance, new_supply); + }) } fn burn_from(env: Env, spender: Address, from: Address, amount: i128) { - Self::extend_instance_ttl_for_call(&env); - Self::panic_on_err(&env, Self::ensure_initialized(&env)); - Self::panic_on_err(&env, Self::ensure_not_paused(&env)); - spender.require_auth(); - if amount <= 0 { - soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); - } + reentrancy_guard!(&env, "burn_from_guard", { + Self::extend_instance_ttl_for_call(&env); + Self::panic_on_err(&env, Self::ensure_initialized(&env)); + Self::panic_on_err(&env, Self::ensure_not_paused(&env)); + spender.require_auth(); + if amount <= 0 { + soroban_sdk::panic_with_error!(&env, TokenError::InvalidAmount); + } - let allowance = Self::allowance_amount(&env, &from, &spender); - if allowance < amount { - soroban_sdk::panic_with_error!(&env, TokenError::InsufficientAllowance); - } + let allowance = Self::allowance_amount(&env, &from, &spender); + if allowance < amount { + soroban_sdk::panic_with_error!(&env, TokenError::InsufficientAllowance); + } - let allowance_data = Self::read_allowance_data(&env, &from, &spender); - let balance = Self::read_balance(&env, &from); - if balance < amount { - soroban_sdk::panic_with_error!(&env, TokenError::InsufficientBalance); - } + let allowance_data = Self::read_allowance_data(&env, &from, &spender); + let balance = Self::read_balance(&env, &from); + if balance < amount { + soroban_sdk::panic_with_error!(&env, TokenError::InsufficientBalance); + } - let new_balance = balance - amount; - let new_supply = Self::read_supply(&env) - amount; - Self::write_allowance( - &env, - &from, - &spender, - allowance - amount, - allowance_data.expiration_ledger, - ); - Self::write_balance(&env, &from, new_balance); - Self::write_supply(&env, new_supply); - events::emit_burn(&env, &from, amount, new_balance, new_supply); + let new_balance = balance - amount; + let new_supply = Self::read_supply(&env) - amount; + Self::write_allowance( + &env, + &from, + &spender, + allowance - amount, + allowance_data.expiration_ledger, + ); + Self::write_balance(&env, &from, new_balance); + Self::write_supply(&env, new_supply); + events::emit_burn(&env, &from, amount, new_balance, new_supply); + }) } fn decimals(env: Env) -> u32 { diff --git a/contracts/token/src/rate_limit.rs b/contracts/token/src/rate_limit.rs index a548ee7..44e2c5c 100644 --- a/contracts/token/src/rate_limit.rs +++ b/contracts/token/src/rate_limit.rs @@ -4,6 +4,7 @@ //! to enforce rate limiting on mint and transfer operations. use soroban_sdk::{Address, Env, String}; +pub use bc_forge_rate_limit::BcForgeRateLimit; /// Operation types for rate limiting pub const OPERATION_MINT: &str = "mint"; @@ -19,7 +20,7 @@ pub fn check_mint_rate_limit(env: &Env, address: &Address, amount: i128) -> bool let amount_u64 = if amount < 0 { 0 } else { amount as u64 }; // Check both global and per-address limits - BcForgeRateLimit::check_rate_limit( + BcForgeRateLimit::check_rate_limit_lib( env, Some(address), String::from_str(env, OPERATION_MINT), @@ -33,7 +34,7 @@ pub fn check_transfer_rate_limit(env: &Env, from: &Address, amount: i128) -> boo let amount_u64 = if amount < 0 { 0 } else { amount as u64 }; // Check both global and per-address limits - BcForgeRateLimit::check_rate_limit( + BcForgeRateLimit::check_rate_limit_lib( env, Some(from), String::from_str(env, OPERATION_TRANSFER), @@ -47,7 +48,7 @@ pub fn check_transfer_from_rate_limit(env: &Env, spender: &Address, amount: i128 let amount_u64 = if amount < 0 { 0 } else { amount as u64 }; // Check both global and per-address limits - BcForgeRateLimit::check_rate_limit( + BcForgeRateLimit::check_rate_limit_lib( env, Some(spender), String::from_str(env, OPERATION_TRANSFER_FROM), @@ -61,7 +62,7 @@ pub fn check_burn_rate_limit(env: &Env, from: &Address, amount: i128) -> bool { let amount_u64 = if amount < 0 { 0 } else { amount as u64 }; // Check both global and per-address limits - BcForgeRateLimit::check_rate_limit( + BcForgeRateLimit::check_rate_limit_lib( env, Some(from), String::from_str(env, OPERATION_BURN), @@ -75,7 +76,7 @@ pub fn check_burn_from_rate_limit(env: &Env, spender: &Address, amount: i128) -> let amount_u64 = if amount < 0 { 0 } else { amount as u64 }; // Check both global and per-address limits - BcForgeRateLimit::check_rate_limit( + BcForgeRateLimit::check_rate_limit_lib( env, Some(spender), String::from_str(env, OPERATION_BURN_FROM), diff --git a/contracts/token/src/reentrancy_guard.rs b/contracts/token/src/reentrancy_guard.rs index 9e01b2c..4a06d7e 100644 --- a/contracts/token/src/reentrancy_guard.rs +++ b/contracts/token/src/reentrancy_guard.rs @@ -3,7 +3,7 @@ //! Implements a reentrancy protection pattern to prevent cross-contract callback attacks. //! This guard ensures that state-modifying functions cannot be re-entered during execution. -use soroban_sdk::{contracttype, Env, StorageType}; +use soroban_sdk::{contracttype, Env, Symbol}; /// Reentrancy guard state #[derive(Clone, Debug, PartialEq)] @@ -16,7 +16,6 @@ pub enum ReentrancyGuardState { } /// Reentrancy guard for preventing re-entrant calls -#[contracttype] pub struct ReentrancyGuard { /// Storage key for the guard state pub state_key: &'static str, @@ -30,10 +29,11 @@ impl ReentrancyGuard { /// Enters the guard - returns true if successful, false if already entered pub fn enter(&self, env: &Env) -> bool { + let key = Symbol::new(env, self.state_key); let current_state = env .storage() .persistent() - .get::<_, ReentrancyGuardState>(self.state_key) + .get::<_, ReentrancyGuardState>(&key) .unwrap_or(ReentrancyGuardState::NotEntered); if current_state == ReentrancyGuardState::Entered { @@ -42,23 +42,25 @@ impl ReentrancyGuard { env.storage() .persistent() - .set(self.state_key, &ReentrancyGuardState::Entered); + .set(&key, &ReentrancyGuardState::Entered); true } /// Exits the guard pub fn exit(&self, env: &Env) { + let key = Symbol::new(env, self.state_key); env.storage() .persistent() - .set(self.state_key, &ReentrancyGuardState::NotEntered); + .set(&key, &ReentrancyGuardState::NotEntered); } /// Checks if the guard is currently entered pub fn is_entered(&self, env: &Env) -> bool { + let key = Symbol::new(env, self.state_key); let current_state = env .storage() .persistent() - .get::<_, ReentrancyGuardState>(self.state_key) + .get::<_, ReentrancyGuardState>(&key) .unwrap_or(ReentrancyGuardState::NotEntered); current_state == ReentrancyGuardState::Entered } diff --git a/contracts/token/src/test.rs b/contracts/token/src/test.rs index d2865e8..19460e6 100644 --- a/contracts/token/src/test.rs +++ b/contracts/token/src/test.rs @@ -1,7 +1,7 @@ #![cfg(test)] use soroban_sdk::testutils::Address as _; -use soroban_sdk::{Address, Env, String}; +use soroban_sdk::{Address, Env, String, vec}; use crate::{BcForgeToken, BcForgeTokenClient, Recipient, TokenError}; @@ -25,6 +25,8 @@ fn test_mint_transfer_and_supply() { let env = Env::default(); env.mock_all_auths(); let (client, _admin) = setup(&env); + let from = Address::generate(&env); + let to = Address::generate(&env); client.mint(&from, &1_000); client.transfer(&from, &to, &300); @@ -141,9 +143,7 @@ fn test_batch_mint_rejects_invalid_amount() { let res = client.try_batch_mint(&recipients); assert_eq!( res, - Err(Ok(soroban_sdk::Error::from_contract_error( - TokenError::InvalidAmount as u32 - ))) + Err(Ok(TokenError::InvalidAmount)) ); // Verify atomic rollback (no tokens minted) @@ -172,9 +172,7 @@ fn test_batch_mint_while_paused_fails() { let res = client.try_batch_mint(&recipients); assert_eq!( res, - Err(Ok(soroban_sdk::Error::from_contract_error( - TokenError::ContractPaused as u32 - ))) + Err(Ok(TokenError::ContractPaused)) ); // Verify no tokens minted diff --git a/contracts/vesting/Cargo.toml b/contracts/vesting/Cargo.toml index 63a0eec..c461410 100644 --- a/contracts/vesting/Cargo.toml +++ b/contracts/vesting/Cargo.toml @@ -11,12 +11,12 @@ license = "MIT" crate-type = ["cdylib", "rlib"] [dependencies] -soroban-sdk = "22.0.0" +soroban-sdk = "26.0.1" bc-forge-admin = { path = "../admin" } bc-forge-token = { path = "../token" } [dev-dependencies] -soroban-sdk = { version = "22.0.0", features = ["testutils"] } +soroban-sdk = { version = "26.0.1", features = ["testutils"] } bc-forge-token = { path = "../token", features = ["testutils"] } [features] diff --git a/contracts/wrapper/Cargo.toml b/contracts/wrapper/Cargo.toml index 45959ee..1e1a0bd 100644 --- a/contracts/wrapper/Cargo.toml +++ b/contracts/wrapper/Cargo.toml @@ -13,12 +13,12 @@ categories = ["cryptography::cryptocurrencies"] crate-type = ["cdylib", "rlib"] [dependencies] -soroban-sdk = "22.0.0" +soroban-sdk = "26.0.1" bc-forge-admin = { path = "../admin" } bc-forge-lifecycle = { path = "../lifecycle" } [dev-dependencies] -soroban-sdk = { version = "22.0.0", features = ["testutils"] } +soroban-sdk = { version = "26.0.1", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] diff --git a/contracts/wrapper/src/lib.rs b/contracts/wrapper/src/lib.rs index 8a43322..fe04ae6 100644 --- a/contracts/wrapper/src/lib.rs +++ b/contracts/wrapper/src/lib.rs @@ -18,7 +18,7 @@ mod events; use bc_forge_admin as admin; use soroban_sdk::token::TokenInterface; use soroban_sdk::{ - contract, contracterror, contractimpl, contracttype, token::TokenClient, Address, Env, String, + contract, contracterror, contractimpl, contracttype, token::TokenClient, Address, Env, String, MuxedAddress, }; // ─── Storage Keys ──────────────────────────────────────────────────────────── @@ -432,7 +432,7 @@ impl TokenInterface for WrapperContract { Self::read_balance(&env, &id) } - fn transfer(env: Env, from: Address, to: Address, amount: i128) { + fn transfer(env: Env, from: Address, to: MuxedAddress, amount: i128) { Self::panic_on_err(&env, Self::ensure_initialized(&env)); Self::panic_on_err(&env, Self::ensure_not_paused(&env)); from.require_auth(); @@ -441,8 +441,9 @@ impl TokenInterface for WrapperContract { soroban_sdk::panic_with_error!(&env, WrapperError::InvalidAmount); } - Self::panic_on_err(&env, Self::move_balance(&env, &from, &to, amount)); - events::emit_transfer(&env, &from, &to, amount); + let to_addr = to.address(); + Self::panic_on_err(&env, Self::move_balance(&env, &from, &to_addr, amount)); + events::emit_transfer(&env, &from, &to_addr, amount); } fn transfer_from(env: Env, spender: Address, from: Address, to: Address, amount: i128) { diff --git a/e2e/integration_test.rs b/e2e/integration_test.rs index eed933c..fdd6109 100644 --- a/e2e/integration_test.rs +++ b/e2e/integration_test.rs @@ -9,12 +9,12 @@ use soroban_sdk::{Address, Env, String}; use bc_forge_token::{BcForgeToken, BcForgeTokenClient}; /// Helper to get testnet RPC URL from environment or use default -fn get_testnet_rpc_url() -> String { +fn get_testnet_rpc_url() -> std::string::String { env::var("STELLAR_TESTNET_RPC_URL").unwrap_or_else(|_| "https://soroban-testnet.stellar.org".to_string()) } /// Helper to get testnet network passphrase -fn get_testnet_network_passphrase() -> String { +fn get_testnet_network_passphrase() -> std::string::String { env::var("STELLAR_TESTNET_PASSPHRASE").unwrap_or_else(|_| "Test SDF Network ; September 2015".to_string()) } @@ -103,7 +103,7 @@ async fn test_deployment_verification() { client.initialize(&admin, &7, &name, &symbol); // Verify contract version - assert_eq!(client.version(), "1.1.0"); + assert_eq!(client.version(), String::from_str(&env, "1.1.0")); println!("✅ Deployment verification test passed!"); }