diff --git a/live-session/week-6/soroban-hello-world/contracts/todo_contract/test_snapshots/test/test_complete_todo.1.json b/live-session/week-6/soroban-hello-world/contracts/todo_contract/test_snapshots/test/test_complete_todo.1.json new file mode 100644 index 000000000..524e0d2d4 --- /dev/null +++ b/live-session/week-6/soroban-hello-world/contracts/todo_contract/test_snapshots/test/test_complete_todo.1.json @@ -0,0 +1,177 @@ +{ + "generators": { + "address": 1, + "nonce": 0 + }, + "auth": [ + [], + [], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "symbol": "NEXT_ID" + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "symbol": "NEXT_ID" + }, + "durability": "persistent", + "val": { + "u32": 2 + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "symbol": "TOD0S" + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "symbol": "TOD0S" + }, + "durability": "persistent", + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "description" + }, + "val": { + "string": "Attend Oscafest on saturday" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "bool": true + } + }, + { + "key": { + "symbol": "title" + }, + "val": { + "string": "Attend Oscafest" + } + } + ] + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/live-session/week-6/soroban-hello-world/contracts/todo_contract/test_snapshots/test/test_get_todos.1.json b/live-session/week-6/soroban-hello-world/contracts/todo_contract/test_snapshots/test/test_get_todos.1.json new file mode 100644 index 000000000..bf1258d56 --- /dev/null +++ b/live-session/week-6/soroban-hello-world/contracts/todo_contract/test_snapshots/test/test_get_todos.1.json @@ -0,0 +1,176 @@ +{ + "generators": { + "address": 1, + "nonce": 0 + }, + "auth": [ + [], + [], + [] + ], + "ledger": { + "protocol_version": 22, + "sequence_number": 0, + "timestamp": 0, + "network_id": "0000000000000000000000000000000000000000000000000000000000000000", + "base_reserve": 0, + "min_persistent_entry_ttl": 4096, + "min_temp_entry_ttl": 16, + "max_entry_ttl": 6312000, + "ledger_entries": [ + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "symbol": "NEXT_ID" + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "symbol": "NEXT_ID" + }, + "durability": "persistent", + "val": { + "u32": 2 + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "symbol": "TOD0S" + }, + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": { + "symbol": "TOD0S" + }, + "durability": "persistent", + "val": { + "vec": [ + { + "map": [ + { + "key": { + "symbol": "description" + }, + "val": { + "string": "Assignment for week6 day4" + } + }, + { + "key": { + "symbol": "id" + }, + "val": { + "u32": 1 + } + }, + { + "key": { + "symbol": "status" + }, + "val": { + "bool": false + } + }, + { + "key": { + "symbol": "title" + }, + "val": { + "string": "Assignment " + } + } + ] + } + ] + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_data": { + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_data": { + "ext": "v0", + "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", + "key": "ledger_key_contract_instance", + "durability": "persistent", + "val": { + "contract_instance": { + "executable": { + "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "storage": null + } + } + } + }, + "ext": "v0" + }, + 4095 + ] + ], + [ + { + "contract_code": { + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + }, + [ + { + "last_modified_ledger_seq": 0, + "data": { + "contract_code": { + "ext": "v0", + "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "code": "" + } + }, + "ext": "v0" + }, + 4095 + ] + ] + ] + }, + "events": [] +} \ No newline at end of file diff --git a/submissions/week-1/day-4/Anuoluwapo-Ali/Task-1/.gitignore b/submissions/week-1/day-4/Anuoluwapo-Ali/Task-1/.gitignore index e69de29bb..9f970225a 100644 --- a/submissions/week-1/day-4/Anuoluwapo-Ali/Task-1/.gitignore +++ b/submissions/week-1/day-4/Anuoluwapo-Ali/Task-1/.gitignore @@ -0,0 +1 @@ +target/ \ No newline at end of file diff --git a/submissions/week-1/day-4/Anuoluwapo-Ali/Task-2/.gitignore b/submissions/week-1/day-4/Anuoluwapo-Ali/Task-2/.gitignore index e69de29bb..9f970225a 100644 --- a/submissions/week-1/day-4/Anuoluwapo-Ali/Task-2/.gitignore +++ b/submissions/week-1/day-4/Anuoluwapo-Ali/Task-2/.gitignore @@ -0,0 +1 @@ +target/ \ No newline at end of file diff --git a/submissions/week-1/day-5/Anuoluwapo_Ali/Task-1/Cargo.lock b/submissions/week-1/day-5/Anuoluwapo_Ali/Task-1/Cargo.lock new file mode 100644 index 000000000..8d81f3da8 --- /dev/null +++ b/submissions/week-1/day-5/Anuoluwapo_Ali/Task-1/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "Task-1" +version = "0.1.0" diff --git a/submissions/week-1/day-5/Anuoluwapo_Ali/Task-2/Cargo.lock b/submissions/week-1/day-5/Anuoluwapo_Ali/Task-2/Cargo.lock new file mode 100644 index 000000000..5869fc338 --- /dev/null +++ b/submissions/week-1/day-5/Anuoluwapo_Ali/Task-2/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "Task-2" +version = "0.1.0" diff --git a/submissions/week-4-codes/day-2/Anuoluwapo b/submissions/week-4-codes/day-2/Anuoluwapo new file mode 160000 index 000000000..5b3fa18f7 --- /dev/null +++ b/submissions/week-4-codes/day-2/Anuoluwapo @@ -0,0 +1 @@ +Subproject commit 5b3fa18f70ff58b8964b089be688f9616de54499 diff --git a/submissions/week-4-codes/day-5/Anuoluwapo b/submissions/week-4-codes/day-5/Anuoluwapo new file mode 160000 index 000000000..11e4ceb39 --- /dev/null +++ b/submissions/week-4-codes/day-5/Anuoluwapo @@ -0,0 +1 @@ +Subproject commit 11e4ceb392a797dd418bcc5514d5fffa77f4674f diff --git a/submissions/week-4/Alfred-Olumide-Adenigba/task-node/running transfer script l1.png b/submissions/week-4/Alfred-Olumide-Adenigba/task-node/running transfer script l1.png index 101d33b7c..69318f274 100644 Binary files a/submissions/week-4/Alfred-Olumide-Adenigba/task-node/running transfer script l1.png and b/submissions/week-4/Alfred-Olumide-Adenigba/task-node/running transfer script l1.png differ diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/.gitignore b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/.gitignore new file mode 100644 index 000000000..f273f39b9 --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/.gitignore @@ -0,0 +1,7 @@ +# Rust's output directory +target + +# Local settings +.soroban +.stellar +/contracts/test_snapshots/ \ No newline at end of file diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/Cargo.lock b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/Cargo.lock new file mode 100644 index 000000000..57908e386 --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/Cargo.lock @@ -0,0 +1,1660 @@ +# 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 = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[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 = "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.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" + +[[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 = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[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 2.0.106", +] + +[[package]] +name = "cc" +version = "1.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ee0f8803222ba5a7e2777dd72ca451868909b1ac410621b676adf07280e9b5f" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "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", + "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.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn 2.0.106", +] + +[[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 2.0.106", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[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 2.0.106", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[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.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[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 = "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", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b" + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" + +[[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.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +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 = "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.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown 0.15.5", + "serde", +] + +[[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.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[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 = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[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 2.0.106", +] + +[[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.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[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", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[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 = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "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.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[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.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "serde_json" +version = "1.0.143" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.10.0", + "schemars 0.9.0", + "schemars 1.0.4", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "soroban-builtin-sdk-macros" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2e42bf80fcdefb3aae6ff3c7101a62cf942e95320ed5b518a1705bc11c6b2f" +dependencies = [ + "itertools", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "soroban-env-common" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "027cd856171bfd6ad2c0ffb3b7dfe55ad7080fb3050c36ad20970f80da634472" +dependencies = [ + "arbitrary", + "crate-git-revision", + "ethnum", + "num-derive", + "num-traits", + "serde", + "soroban-env-macros", + "soroban-wasmi", + "static_assertions", + "stellar-xdr", + "wasmparser", +] + +[[package]] +name = "soroban-env-guest" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a07dda1ae5220d975979b19ad4fd56bc86ec7ec1b4b25bc1c5d403f934e592e" +dependencies = [ + "soroban-env-common", + "static_assertions", +] + +[[package]] +name = "soroban-env-host" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66e8b03a4191d485eab03f066336112b2a50541a7553179553dc838b986b94dd" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", + "curve25519-dalek", + "ecdsa", + "ed25519-dalek", + "elliptic-curve", + "generic-array", + "getrandom", + "hex-literal", + "hmac", + "k256", + "num-derive", + "num-integer", + "num-traits", + "p256", + "rand", + "rand_chacha", + "sec1", + "sha2", + "sha3", + "soroban-builtin-sdk-macros", + "soroban-env-common", + "soroban-wasmi", + "static_assertions", + "stellar-strkey", + "wasmparser", +] + +[[package]] +name = "soroban-env-macros" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00eff744764ade3bc480e4909e3a581a240091f3d262acdce80b41f7069b2bd9" +dependencies = [ + "itertools", + "proc-macro2", + "quote", + "serde", + "serde_json", + "stellar-xdr", + "syn 2.0.106", +] + +[[package]] +name = "soroban-ledger-snapshot" +version = "22.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2826e2c9d364edbb2ea112dc861077c74557bdad0a7a00487969088c7c648169" +dependencies = [ + "serde", + "serde_json", + "serde_with", + "soroban-env-common", + "soroban-env-host", + "thiserror", +] + +[[package]] +name = "soroban-sdk" +version = "22.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ac27d7573e62b745513fa1be8dab7a09b9676a7f39db97164f1d458a344749" +dependencies = [ + "arbitrary", + "bytes-lit", + "ctor", + "derive_arbitrary", + "ed25519-dalek", + "rand", + "rustc_version", + "serde", + "serde_json", + "soroban-env-guest", + "soroban-env-host", + "soroban-ledger-snapshot", + "soroban-sdk-macros", + "stellar-strkey", +] + +[[package]] +name = "soroban-sdk-macros" +version = "22.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef0d7d62b2584696d306b8766728971c7d0731a03a5e047f1fc68722ac8cf0c" +dependencies = [ + "crate-git-revision", + "darling", + "itertools", + "proc-macro2", + "quote", + "rustc_version", + "sha2", + "soroban-env-common", + "soroban-spec", + "soroban-spec-rust", + "stellar-xdr", + "syn 2.0.106", +] + +[[package]] +name = "soroban-spec" +version = "22.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4ad0867aec99770ed614fedbec7ac4591791df162ff9e548ab7ebd07cd23a9c" +dependencies = [ + "base64 0.13.1", + "stellar-xdr", + "thiserror", + "wasmparser", +] + +[[package]] +name = "soroban-spec-rust" +version = "22.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aebe31c042adfa2885ec47b67b08fcead8707da80a3fe737eaf2a9ae1a8cfdc3" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "sha2", + "soroban-spec", + "stellar-xdr", + "syn 2.0.106", + "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 = "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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e3aa3ed00e70082cb43febc1c2afa5056b9bb3e348bbb43d0cd0aa88a611144" +dependencies = [ + "crate-git-revision", + "data-encoding", + "thiserror", +] + +[[package]] +name = "stellar-xdr" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ce69db907e64d1e70a3dce8d4824655d154749426a6132b25395c49136013e4" +dependencies = [ + "arbitrary", + "base64 0.13.1", + "crate-git-revision", + "escape-bytes", + "hex", + "serde", + "serde_with", + "stellar-strkey", +] + +[[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 = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[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 2.0.106", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "token-contract" +version = "0.0.0" +dependencies = [ + "soroban-sdk", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.106", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[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.10.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.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/Cargo.toml b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/Cargo.toml new file mode 100644 index 000000000..a04ea4fb3 --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/Cargo.toml @@ -0,0 +1,23 @@ +[workspace] +resolver = "2" +members = [ + "contracts/*", +] + +[workspace.dependencies] +soroban-sdk = "22.0.0" + +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true + +# For more information about this profile see https://soroban.stellar.org/docs/basic-tutorials/logging#cargotoml-profile +[profile.release-with-logs] +inherits = "release" +debug-assertions = true diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/README.md b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/README.md new file mode 100644 index 000000000..012e23c44 --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/README.md @@ -0,0 +1,21 @@ +# Soroban Project + +## Project Structure + +This repository uses the recommended structure for a Soroban project: +```text +. +├── contracts +│   └── hello_world +│   ├── src +│   │   ├── lib.rs +│   │   └── test.rs +│   └── Cargo.toml +├── Cargo.toml +└── README.md +``` + +- New Soroban contracts can be put in `contracts`, each in their own directory. There is already a `hello_world` contract in there to get you started. +- If you initialized this project with any other example contracts via `--with-example`, those contracts will be in the `contracts` directory as well. +- Contracts should have their own `Cargo.toml` files that rely on the top-level `Cargo.toml` workspace for their dependencies. +- Frontend libraries can be added to the top-level directory as well. If you initialized this project with a frontend template via `--frontend-template` you will have those files already included. \ No newline at end of file diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/Cargo.toml b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/Cargo.toml new file mode 100644 index 000000000..9c2bc551e --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "token-contract" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["lib", "cdylib"] +doctest = false + +[dependencies] +soroban-sdk = { workspace = true } + +[dev-dependencies] +soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/Makefile b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/Makefile new file mode 100644 index 000000000..b9719346b --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/Makefile @@ -0,0 +1,16 @@ +default: build + +all: test + +test: build + cargo test + +build: + stellar contract build + @ls -l target/wasm32v1-none/release/*.wasm + +fmt: + cargo fmt --all + +clean: + cargo clean diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/admin.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/admin.rs new file mode 100644 index 000000000..cc91f1029 --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/admin.rs @@ -0,0 +1,18 @@ +use soroban_sdk::{Address, Env}; +use crate::helpers::{set_admin, get_admin}; +use crate::errors::TokenError; + +pub fn require_admin(env: &Env, addr: &Address) -> Result<(), TokenError> { + let admin = get_admin(env); + if *addr != admin { + return Err(TokenError::Unauthorized); + } + Ok(()) +} + +pub fn change_admin(env: &Env, current_admin: &Address, new_admin: &Address) -> Result<(), TokenError> { + current_admin.require_auth(); + require_admin(env, current_admin)?; + set_admin(env, new_admin); + Ok(()) +} \ No newline at end of file diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/allowance.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/allowance.rs new file mode 100644 index 000000000..31bcc7d74 --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/allowance.rs @@ -0,0 +1,38 @@ +use soroban_sdk::{Address, Env}; +use crate::helpers::{get_allowance, set_allowance, get_allowance_expiration, set_allowance_expiration}; +use crate::errors::TokenError; + +pub fn approve_allowance( + env: &Env, + owner: &Address, + spender: &Address, + amount: &i128, + expiration_ledger: &u32, +) -> Result<(), TokenError> { + owner.require_auth(); + + if *amount < 0 { + return Err(TokenError::InvalidAmount); + } + + let current_ledger = env.ledger().sequence(); + if *expiration_ledger <= current_ledger { + return Err(TokenError::InvalidExpiration); + } + + set_allowance(env, owner, spender, amount); + set_allowance_expiration(env, owner, spender, expiration_ledger); + + Ok(()) +} + +pub fn check_allowance(env: &Env, owner: &Address, spender: &Address) -> i128 { + let expiration = get_allowance_expiration(env, owner, spender); + let current_ledger = env.ledger().sequence(); + + if expiration <= current_ledger { + return 0; + } + + get_allowance(env, owner, spender) +} \ No newline at end of file diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/balance.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/balance.rs new file mode 100644 index 000000000..71b32b899 --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/balance.rs @@ -0,0 +1,31 @@ +use soroban_sdk::{Address, Env}; +use crate::helper::{get_balance, set_balance, get_frozen}; +use crate::errors::TokenError; + +pub fn transfer_balance(env: &Env, from: &Address, to: &Address, amount: &i128) -> Result<(), TokenError> { + if *amount <= 0 { + return Err(TokenError::InvalidAmount); + } + + if get_frozen(env, from) { + return Err(TokenError::AccountFrozen); + } + + if get_frozen(env, to) { + return Err(TokenError::AccountFrozen); + } + + let from_balance = get_balance(env, from); + if from_balance < *amount { + return Err(TokenError::InsufficientBalance); + } + + set_balance(env, from, &(from_balance - amount)); + + let to_balance = get_balance(env, to); + let new_balance = to_balance.checked_add(*amount) + .ok_or(TokenError::BalanceOverflow)?; + set_balance(env, to, &new_balance); + + Ok(()) +} \ No newline at end of file diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/errors.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/errors.rs new file mode 100644 index 000000000..95def4928 --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/errors.rs @@ -0,0 +1,23 @@ +use soroban_sdk::contracterror; + +#[contracterror] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +#[repr(u32)] +pub enum TokenError { + AlreadyInitialized = 1, + NameTooLong = 2, + SymbolTooLong = 3, + DecimalsTooHigh = 4, + InvalidTotalSupply = 5, + InvalidAmount = 6, + InsufficientBalance = 7, + InsufficientAllowance = 8, + AccountFrozen = 9, + InvalidExpiration = 10, + BalanceOverflow = 11, + SupplyOverflow = 12, + NotInitialized = 13, + Unauthorized = 14, + BalanceUnderflow = 15, + DecimalTooLong = 16, +} \ No newline at end of file diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/helpers.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/helpers.rs new file mode 100644 index 000000000..91fc2438c --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/helpers.rs @@ -0,0 +1,102 @@ +use soroban_sdk::{Address, Env, String}; +use crate::types::DataKey; + +pub fn set_admin(env: &Env, admin: &Address) { + env.storage().instance().set(&DataKey::Admin, admin); +} + +pub fn get_admin(env: &Env) -> Address { + env.storage().instance().get(&DataKey::Admin).unwrap() +} + +pub fn has_admin(env: &Env) -> bool { + env.storage().instance().has(&DataKey::Admin) +} + +pub fn set_balance(env: &Env, addr: &Address, amount: &i128) { + let key = DataKey::Balance(addr.clone()); + if *amount == 0 { + env.storage().persistent().remove(&key); + } else { + env.storage().persistent().set(&key, amount); + env.storage().persistent().extend_ttl(&key, 100, 100); + } +} + +pub fn get_balance(env: &Env, addr: &Address) -> i128 { + let key = DataKey::Balance(addr.clone()); + env.storage().persistent().get(&key).unwrap_or(0) +} + +pub fn set_allowance(env: &Env, owner: &Address, spender: &Address, amount: &i128) { + let key = DataKey::Allowance(owner.clone(), spender.clone()); + if *amount == 0 { + env.storage().persistent().remove(&key); + } else { + env.storage().persistent().set(&key, amount); + env.storage().persistent().extend_ttl(&key, 100, 100); + } +} + +pub fn get_allowance(env: &Env, owner: &Address, spender: &Address) -> i128 { + let key = DataKey::Allowance(owner.clone(), spender.clone()); + env.storage().persistent().get(&key).unwrap_or(0) +} + +pub fn set_allowance_expiration(env: &Env, owner: &Address, spender: &Address, expiration: &u32) { + let key = DataKey::AllowanceExpiration(owner.clone(), spender.clone()); + env.storage().persistent().set(&key, expiration); + env.storage().persistent().extend_ttl(&key, 100, 100); +} + +pub fn get_allowance_expiration(env: &Env, owner: &Address, spender: &Address) -> u32 { + let key = DataKey::AllowanceExpiration(owner.clone(), spender.clone()); + env.storage().persistent().get(&key).unwrap_or(0) +} + +pub fn set_frozen(env: &Env, addr: &Address, frozen: &bool) { + let key = DataKey::Frozen(addr.clone()); + if *frozen { + env.storage().persistent().set(&key, frozen); + env.storage().persistent().extend_ttl(&key, 100, 100); + } else { + env.storage().persistent().remove(&key); + } +} + +pub fn get_frozen(env: &Env, addr: &Address) -> bool { + let key = DataKey::Frozen(addr.clone()); + env.storage().persistent().get(&key).unwrap_or(false) +} + +pub fn set_name(env: &Env, name: &String) { + env.storage().instance().set(&DataKey::Name, name); +} + +pub fn get_name(env: &Env) -> String { + env.storage().instance().get(&DataKey::Name).unwrap() +} + +pub fn set_symbol(env: &Env, symbol: &String) { + env.storage().instance().set(&DataKey::Symbol, symbol); +} + +pub fn get_symbol(env: &Env) -> String { + env.storage().instance().get(&DataKey::Symbol).unwrap() +} + +pub fn set_decimals(env: &Env, decimals: &u32) { + env.storage().instance().set(&DataKey::Decimals, decimals); +} + +pub fn get_decimals(env: &Env) -> u32 { + env.storage().instance().get(&DataKey::Decimals).unwrap() +} + +pub fn set_total_supply(env: &Env, total_supply: &i128) { + env.storage().instance().set(&DataKey::TotalSupply, total_supply); +} + +pub fn get_total_supply(env: &Env) -> i128 { + env.storage().instance().get(&DataKey::TotalSupply).unwrap() +} diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/lib.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/lib.rs new file mode 100644 index 000000000..53d28b5e2 --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/lib.rs @@ -0,0 +1,15 @@ +#![no_std] + +mod errors; +mod import; +mod events; +mod helpers; +mod metadata; +mod traits; +mod types; +mod admin; +mod allowance; +mod Sep_41; +mod test; + +pub use Sep_41::*; \ No newline at end of file diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/metadata.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/metadata.rs new file mode 100644 index 000000000..e69de29bb diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/sep_41.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/sep_41.rs new file mode 100644 index 000000000..9815edf5e --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/sep_41.rs @@ -0,0 +1,305 @@ +#![no_std] +use soroban_sdk::{contract, contractimpl, contractmeta, panic_with_error, Address, Env, String}; + +pub mod admin; +pub mod allowance; +pub mod balance; +pub mod metadata; +pub mod helpers; +pub mod types; +pub mod traits; +pub mod errors; + +pub use admin::*; +pub use allowance::*; +pub use balance::*; +pub use metadata::*; +pub use helpers::*; +pub use types::*; +pub use traits::*; +pub use errors::*; + +contractmeta!( + key = "Description", + val = "SEP-41 Compliant Fungible Token Contract" +); + +contractmeta!( + key = "version", + val = "1.0.0" +); + +#[contract] +pub struct Token; + +#[contractimpl] +impl Token { + pub fn initialize( + env: Env, + admin: Address, + name: String, + symbol: String, + decimals: u32, + total_supply: i128, + ) -> Result<(), TokenError> { + if has_admin(&env) { + return Err(TokenError::AlreadyInitialized); + } + + admin.require_auth(); + + if name.len() > 32 { + return Err(TokenError::NameTooLong); + } + + if symbol.len() > 16 { + return Err(TokenError::SymbolTooLong); + } + + if decimals > 18 { + return Err(TokenError::DecimalsTooHigh); + } + + if total_supply < 0 { + return Err(TokenError::InvalidTotalSupply); + } + + set_admin(&env, &admin); + set_name(&env, &name); + set_symbol(&env, &symbol); + set_decimals(&env, &decimals); + set_total_supply(&env, &total_supply); + + if total_supply > 0 { + set_balance(&env, &admin, &total_supply); + } + + Ok(()) + } + + pub fn transfer(env: Env, from: Address, to: Address, amount: i128) -> Result<(), TokenError> { + from.require_auth(); + Self::transfer_impl(&env, &from, &to, &amount) + } + + pub fn transfer_from(env: Env, spender: Address, from: Address, to: Address, amount: i128) -> Result<(), TokenError> { + spender.require_auth(); + + let allowance = get_allowance(&env, &from, &spender); + if allowance < amount { + return Err(TokenError::InsufficientAllowance); + } + + set_allowance(&env, &from, &spender, &(allowance - amount)); + Self::transfer_impl(&env, &from, &to, &amount) + } + + fn transfer_impl(env: &Env, from: &Address, to: &Address, amount: &i128) -> Result<(), TokenError> { + if *amount < 0 { + return Err(TokenError::InvalidAmount); + } + + if *amount == 0 { + return Ok(()); + } + + if from == to { + return Ok(()); + } + + if get_frozen(env, from) { + return Err(TokenError::AccountFrozen); + } + + if get_frozen(env, to) { + return Err(TokenError::AccountFrozen); + } + + let from_balance = get_balance(env, from); + if from_balance < *amount { + return Err(TokenError::InsufficientBalance); + } + + set_balance(env, from, &(from_balance - amount)); + let to_balance = get_balance(env, to); + let new_to_balance = to_balance.checked_add(*amount) + .ok_or(TokenError::BalanceOverflow)?; + set_balance(env, to, &new_to_balance); + + Ok(()) + } + + pub fn balance(env: Env, id: Address) -> i128 { + get_balance(&env, &id) + } + + pub fn approve( + env: Env, + from: Address, + spender: Address, + amount: i128, + expiration_ledger: u32, + ) -> Result<(), TokenError> { + from.require_auth(); + + if amount < 0 { + return Err(TokenError::InvalidAmount); + } + + let current_ledger = env.ledger().sequence(); + if expiration_ledger <= current_ledger { + return Err(TokenError::InvalidExpiration); + } + + set_allowance(&env, &from, &spender, &amount); + set_allowance_expiration(&env, &from, &spender, &expiration_ledger); + + Ok(()) + } + + pub fn allowance(env: Env, from: Address, spender: Address) -> i128 { + let expiration = get_allowance_expiration(&env, &from, &spender); + let current_ledger = env.ledger().sequence(); + + if expiration <= current_ledger { + return 0; + } + + get_allowance(&env, &from, &spender) + } + + pub fn mint(env: Env, to: Address, amount: i128) -> Result<(), TokenError> { + if !has_admin(&env) { + return Err(TokenError::NotInitialized); + } + + let admin = get_admin(&env); + admin.require_auth(); + + if amount < 0 { + return Err(TokenError::InvalidAmount); + } + + if amount == 0 { + return Ok(()); + } + + if get_frozen(&env, &to) { + return Err(TokenError::AccountFrozen); + } + + let to_balance = get_balance(&env, &to); + let new_balance = to_balance.checked_add(amount) + .ok_or(TokenError::BalanceOverflow)?; + + set_balance(&env, &to, &new_balance); + + let total_supply = get_total_supply(&env); + let new_supply = total_supply.checked_add(amount) + .ok_or(TokenError::SupplyOverflow)?; + + set_total_supply(&env, &new_supply); + + Ok(()) + } + + pub fn burn(env: Env, from: Address, amount: i128) -> Result<(), TokenError> { + from.require_auth(); + Self::burn_impl(&env, &from, &amount) + } + + pub fn burn_from(env: Env, spender: Address, from: Address, amount: i128) -> Result<(), TokenError> { + spender.require_auth(); + + let allowance = get_allowance(&env, &from, &spender); + if allowance < amount { + return Err(TokenError::InsufficientAllowance); + } + + set_allowance(&env, &from, &spender, &(allowance - amount)); + Self::burn_impl(&env, &from, &amount) + } + + fn burn_impl(env: &Env, from: &Address, amount: &i128) -> Result<(), TokenError> { + if *amount < 0 { + return Err(TokenError::InvalidAmount); + } + + if *amount == 0 { + return Ok(()); + } + + let from_balance = get_balance(env, from); + if from_balance < *amount { + return Err(TokenError::InsufficientBalance); + } + + set_balance(env, from, &(from_balance - amount)); + + let total_supply = get_total_supply(env); + set_total_supply(env, &(total_supply - amount)); + + Ok(()) + } + + pub fn set_admin(env: Env, new_admin: Address) -> Result<(), TokenError> { + if !has_admin(&env) { + return Err(TokenError::NotInitialized); + } + + let admin = get_admin(&env); + admin.require_auth(); + set_admin(&env, &new_admin); + + Ok(()) + } + + pub fn admin(env: Env) -> Address { + if !has_admin(&env) { + panic_with_error!(&env, TokenError::NotInitialized); + } + + get_admin(&env) + } + + pub fn name(env: Env) -> String { + get_name(&env) + } + + pub fn symbol(env: Env) -> String { + get_symbol(&env) + } + + pub fn decimals(env: Env) -> u32 { + get_decimals(&env) + } + + pub fn total_supply(env: Env) -> i128 { + get_total_supply(&env) + } + + pub fn freeze_account(env: Env, account: Address) { + if !has_admin(&env) { + panic_with_error!(&env, TokenError::NotInitialized); + } + + let admin = get_admin(&env); + admin.require_auth(); + set_frozen(&env, &account, &true); + } + + pub fn unfreeze_account(env: Env, account: Address) { + if !has_admin(&env) { + panic_with_error!(&env, TokenError::NotInitialized); + } + + let admin = get_admin(&env); + admin.require_auth(); + set_frozen(&env, &account, &false); + } + + pub fn is_frozen(env: Env, account: Address) -> bool { + get_frozen(&env, &account) + } +} + diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/test.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/test.rs new file mode 100644 index 000000000..379286d60 --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/test.rs @@ -0,0 +1,220 @@ +#![cfg(test)] + +use super::*; + use soroban_sdk::{testutils::Address as _, Address, Env, String}; + + fn create_token_contract(e: &Env, admin: &Address) -> Address { + e.register_contract(None, Token {}) + } + + #[test] + fn test_initialize() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + assert_eq!(client.name(), name); + assert_eq!(client.symbol(), symbol); + assert_eq!(client.decimals(), decimals); + assert_eq!(client.total_supply(), total_supply); + assert_eq!(client.admin(), admin); + assert_eq!(client.balance(&admin), total_supply); + } + + #[test] + fn test_transfer() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let user1 = Address::generate(&env); + let user2 = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + let transfer_amount = 100000i128; + client.transfer(&admin, &user1, &transfer_amount); + + assert_eq!(client.balance(&admin), total_supply - transfer_amount); + assert_eq!(client.balance(&user1), transfer_amount); + + let transfer_amount2 = 50000i128; + client.transfer(&user1, &user2, &transfer_amount2); + + assert_eq!(client.balance(&user1), transfer_amount - transfer_amount2); + assert_eq!(client.balance(&user2), transfer_amount2); + } + + #[test] + fn test_approve_and_transfer_from() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let owner = Address::generate(&env); + let spender = Address::generate(&env); + let recipient = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + let owner_amount = 100000i128; + client.transfer(&admin, &owner, &owner_amount); + + let allowance_amount = 50000i128; + let expiration = env.ledger().sequence() + 100; + client.approve(&owner, &spender, &allowance_amount, &expiration); + + assert_eq!(client.allowance(&owner, &spender), allowance_amount); + + let transfer_amount = 30000i128; + client.transfer_from(&spender, &owner, &recipient, &transfer_amount); + + assert_eq!(client.balance(&owner), owner_amount - transfer_amount); + assert_eq!(client.balance(&recipient), transfer_amount); + assert_eq!(client.allowance(&owner, &spender), allowance_amount - transfer_amount); + } + + #[test] + fn test_mint() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let user = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + let mint_amount = 500000i128; + client.mint(&user, &mint_amount); + + assert_eq!(client.balance(&user), mint_amount); + assert_eq!(client.total_supply(), total_supply + mint_amount); + } + + #[test] + fn test_burn() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let user = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + let user_amount = 100000i128; + client.transfer(&admin, &user, &user_amount); + + let burn_amount = 50000i128; + client.burn(&user, &burn_amount); + + assert_eq!(client.balance(&user), user_amount - burn_amount); + assert_eq!(client.total_supply(), total_supply - burn_amount); + } + + #[test] + fn test_freeze_account() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let user = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + client.freeze_account(&user); + assert_eq!(client.is_frozen(&user), true); + + client.unfreeze_account(&user); + assert_eq!(client.is_frozen(&user), false); + } + + #[test] + #[should_panic(expected = "Already initialized")] + fn test_double_initialize() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + } + + #[test] + #[should_panic(expected = "Insufficient balance")] + fn test_insufficient_balance() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let user = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + client.transfer(&user, &admin, &1000i128); + } \ No newline at end of file diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/traits.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/traits.rs new file mode 100644 index 000000000..d1ed6fd6d --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/traits.rs @@ -0,0 +1,57 @@ +use soroban_sdk::{Address, Env}; +use crate::helpers::get_admin; +use crate::errors::TokenError; + +pub trait AdminCheck { + fn require_admin(&self, env: &Env); +} + +impl AdminCheck for Address { + fn require_admin(&self, env: &Env) { + let admin = get_admin(env); + if *self != admin { + panic!("Unauthorized"); + } + } +} + +pub trait TokenValidation { + fn validate_positive_amount(&self); + fn validate_non_zero(&self); +} + +impl TokenValidation for i128 { + fn validate_positive_amount(&self) { + if *self < 0 { + panic!("Invalid amount"); + } + } + + fn validate_non_zero(&self) { + if *self == 0 { + panic!("Balance underflow"); + } + } +} + +pub fn require_admin_result(addr: &Address, env: &Env) -> Result<(), TokenError> { + let admin = get_admin(env); + if *addr != admin { + return Err(TokenError::Unauthorized); + } + Ok(()) +} + +pub fn validate_positive_amount_result(amount: &i128) -> Result<(), TokenError> { + if *amount < 0 { + return Err(TokenError::InvalidAmount); + } + Ok(()) +} + +pub fn validate_non_zero_result(amount: &i128) -> Result<(), TokenError> { + if *amount == 0 { + return Err(TokenError::BalanceUnderflow); + } + Ok(()) +} \ No newline at end of file diff --git a/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/types.rs b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/types.rs new file mode 100644 index 000000000..71b3b31de --- /dev/null +++ b/submissions/week-6/day-4/Anuoluwapo_Ali/SEP-41/contracts/token-contract/src/types.rs @@ -0,0 +1,22 @@ +use soroban_sdk::{contracttype, Address}; + +#[derive(Clone)] +#[contracttype] +pub enum DataKey { + Admin, + Name, + Symbol, + Decimals, + TotalSupply, + Balance(Address), + Allowance(Address, Address), + AllowanceExpiration(Address, Address), + Frozen(Address), +} + +#[derive(Clone)] +#[contracttype] +pub struct AllowanceData { + pub amount: i128, + pub expiration_ledger: u32, +} diff --git a/submissions/week-7/day-2/Anuoluwapo/.gitignore b/submissions/week-7/day-2/Anuoluwapo/.gitignore new file mode 100644 index 000000000..a7480e7c5 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/.gitignore @@ -0,0 +1,8 @@ +# Rust's output directory +target + +# Local settings +.soroban +.stellar + +**/test_snapshots/ diff --git a/submissions/week-7/day-2/Anuoluwapo/Cargo.toml b/submissions/week-7/day-2/Anuoluwapo/Cargo.toml new file mode 100644 index 000000000..a04ea4fb3 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Cargo.toml @@ -0,0 +1,23 @@ +[workspace] +resolver = "2" +members = [ + "contracts/*", +] + +[workspace.dependencies] +soroban-sdk = "22.0.0" + +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true + +# For more information about this profile see https://soroban.stellar.org/docs/basic-tutorials/logging#cargotoml-profile +[profile.release-with-logs] +inherits = "release" +debug-assertions = true diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/.gitignore b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/.gitignore new file mode 100644 index 000000000..5b8897e35 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/.gitignore @@ -0,0 +1,9 @@ +# Rust's output directory +target + +# Local settings +.soroban +.stellar + +**/test_snapshots/ + diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/Cargo.lock b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/Cargo.lock new file mode 100644 index 000000000..9de247c63 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/Cargo.lock @@ -0,0 +1,1667 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "Sep_41" +version = "0.0.0" +dependencies = [ + "soroban-sdk", +] + +[[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 = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[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 = "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.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" + +[[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 = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[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 2.0.106", +] + +[[package]] +name = "cc" +version = "1.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ee0f8803222ba5a7e2777dd72ca451868909b1ac410621b676adf07280e9b5f" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "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", + "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.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn 2.0.106", +] + +[[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 2.0.106", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[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 2.0.106", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[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.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[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 = "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", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "employee_management" +version = "0.0.0" +dependencies = [ + "soroban-sdk", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b" + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" + +[[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.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +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 = "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.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown 0.15.5", + "serde", +] + +[[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.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[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 = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[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 2.0.106", +] + +[[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.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[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", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[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 = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "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.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[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.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "serde_json" +version = "1.0.143" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.10.0", + "schemars 0.9.0", + "schemars 1.0.4", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "soroban-builtin-sdk-macros" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2e42bf80fcdefb3aae6ff3c7101a62cf942e95320ed5b518a1705bc11c6b2f" +dependencies = [ + "itertools", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "soroban-env-common" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "027cd856171bfd6ad2c0ffb3b7dfe55ad7080fb3050c36ad20970f80da634472" +dependencies = [ + "arbitrary", + "crate-git-revision", + "ethnum", + "num-derive", + "num-traits", + "serde", + "soroban-env-macros", + "soroban-wasmi", + "static_assertions", + "stellar-xdr", + "wasmparser", +] + +[[package]] +name = "soroban-env-guest" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a07dda1ae5220d975979b19ad4fd56bc86ec7ec1b4b25bc1c5d403f934e592e" +dependencies = [ + "soroban-env-common", + "static_assertions", +] + +[[package]] +name = "soroban-env-host" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66e8b03a4191d485eab03f066336112b2a50541a7553179553dc838b986b94dd" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", + "curve25519-dalek", + "ecdsa", + "ed25519-dalek", + "elliptic-curve", + "generic-array", + "getrandom", + "hex-literal", + "hmac", + "k256", + "num-derive", + "num-integer", + "num-traits", + "p256", + "rand", + "rand_chacha", + "sec1", + "sha2", + "sha3", + "soroban-builtin-sdk-macros", + "soroban-env-common", + "soroban-wasmi", + "static_assertions", + "stellar-strkey", + "wasmparser", +] + +[[package]] +name = "soroban-env-macros" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00eff744764ade3bc480e4909e3a581a240091f3d262acdce80b41f7069b2bd9" +dependencies = [ + "itertools", + "proc-macro2", + "quote", + "serde", + "serde_json", + "stellar-xdr", + "syn 2.0.106", +] + +[[package]] +name = "soroban-ledger-snapshot" +version = "22.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2826e2c9d364edbb2ea112dc861077c74557bdad0a7a00487969088c7c648169" +dependencies = [ + "serde", + "serde_json", + "serde_with", + "soroban-env-common", + "soroban-env-host", + "thiserror", +] + +[[package]] +name = "soroban-sdk" +version = "22.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ac27d7573e62b745513fa1be8dab7a09b9676a7f39db97164f1d458a344749" +dependencies = [ + "arbitrary", + "bytes-lit", + "ctor", + "derive_arbitrary", + "ed25519-dalek", + "rand", + "rustc_version", + "serde", + "serde_json", + "soroban-env-guest", + "soroban-env-host", + "soroban-ledger-snapshot", + "soroban-sdk-macros", + "stellar-strkey", +] + +[[package]] +name = "soroban-sdk-macros" +version = "22.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef0d7d62b2584696d306b8766728971c7d0731a03a5e047f1fc68722ac8cf0c" +dependencies = [ + "crate-git-revision", + "darling", + "itertools", + "proc-macro2", + "quote", + "rustc_version", + "sha2", + "soroban-env-common", + "soroban-spec", + "soroban-spec-rust", + "stellar-xdr", + "syn 2.0.106", +] + +[[package]] +name = "soroban-spec" +version = "22.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4ad0867aec99770ed614fedbec7ac4591791df162ff9e548ab7ebd07cd23a9c" +dependencies = [ + "base64 0.13.1", + "stellar-xdr", + "thiserror", + "wasmparser", +] + +[[package]] +name = "soroban-spec-rust" +version = "22.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aebe31c042adfa2885ec47b67b08fcead8707da80a3fe737eaf2a9ae1a8cfdc3" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "sha2", + "soroban-spec", + "stellar-xdr", + "syn 2.0.106", + "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 = "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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e3aa3ed00e70082cb43febc1c2afa5056b9bb3e348bbb43d0cd0aa88a611144" +dependencies = [ + "crate-git-revision", + "data-encoding", + "thiserror", +] + +[[package]] +name = "stellar-xdr" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ce69db907e64d1e70a3dce8d4824655d154749426a6132b25395c49136013e4" +dependencies = [ + "arbitrary", + "base64 0.13.1", + "crate-git-revision", + "escape-bytes", + "hex", + "serde", + "serde_with", + "stellar-strkey", +] + +[[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 = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[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 2.0.106", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.106", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[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.10.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.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/Cargo.toml b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/Cargo.toml new file mode 100644 index 000000000..a04ea4fb3 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/Cargo.toml @@ -0,0 +1,23 @@ +[workspace] +resolver = "2" +members = [ + "contracts/*", +] + +[workspace.dependencies] +soroban-sdk = "22.0.0" + +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true + +# For more information about this profile see https://soroban.stellar.org/docs/basic-tutorials/logging#cargotoml-profile +[profile.release-with-logs] +inherits = "release" +debug-assertions = true diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/README.md b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/README.md new file mode 100644 index 000000000..012e23c44 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/README.md @@ -0,0 +1,21 @@ +# Soroban Project + +## Project Structure + +This repository uses the recommended structure for a Soroban project: +```text +. +├── contracts +│   └── hello_world +│   ├── src +│   │   ├── lib.rs +│   │   └── test.rs +│   └── Cargo.toml +├── Cargo.toml +└── README.md +``` + +- New Soroban contracts can be put in `contracts`, each in their own directory. There is already a `hello_world` contract in there to get you started. +- If you initialized this project with any other example contracts via `--with-example`, those contracts will be in the `contracts` directory as well. +- Contracts should have their own `Cargo.toml` files that rely on the top-level `Cargo.toml` workspace for their dependencies. +- Frontend libraries can be added to the top-level directory as well. If you initialized this project with a frontend template via `--frontend-template` you will have those files already included. \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/Cargo.toml b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/Cargo.toml new file mode 100644 index 000000000..416040fe3 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "Sep_41" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["lib", "cdylib"] +doctest = false + +[dependencies] +soroban-sdk = { workspace = true } + +[dev-dependencies] +soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/Makefile b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/Makefile new file mode 100644 index 000000000..b9719346b --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/Makefile @@ -0,0 +1,16 @@ +default: build + +all: test + +test: build + cargo test + +build: + stellar contract build + @ls -l target/wasm32v1-none/release/*.wasm + +fmt: + cargo fmt --all + +clean: + cargo clean diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/admin.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/admin.rs new file mode 100644 index 000000000..2855a670c --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/admin.rs @@ -0,0 +1,18 @@ +use soroban_sdk::{Address, Env}; +use crate::helper::{set_admin, get_admin}; +use crate::errors::TokenError; + +pub fn require_admin(env: &Env, addr: &Address) -> Result<(), TokenError> { + let admin = get_admin(env); + if *addr != admin { + return Err(TokenError::Unauthorized); + } + Ok(()) +} + +pub fn change_admin(env: &Env, current_admin: &Address, new_admin: &Address) -> Result<(), TokenError> { + current_admin.require_auth(); + require_admin(env, current_admin)?; + set_admin(env, new_admin); + Ok(()) +} \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/allowance.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/allowance.rs new file mode 100644 index 000000000..ea52b32a5 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/allowance.rs @@ -0,0 +1,38 @@ +use soroban_sdk::{Address, Env}; +use crate::helper::{get_allowance, set_allowance, get_allowance_expiration, set_allowance_expiration}; +use crate::errors::TokenError; + +pub fn approve_allowance( + env: &Env, + owner: &Address, + spender: &Address, + amount: &i128, + expiration_ledger: &u32, +) -> Result<(), TokenError> { + owner.require_auth(); + + if *amount < 0 { + return Err(TokenError::InvalidAmount); + } + + let current_ledger = env.ledger().sequence(); + if *expiration_ledger <= current_ledger { + return Err(TokenError::InvalidExpiration); + } + + set_allowance(env, owner, spender, amount); + set_allowance_expiration(env, owner, spender, expiration_ledger); + + Ok(()) +} + +pub fn check_allowance(env: &Env, owner: &Address, spender: &Address) -> i128 { + let expiration = get_allowance_expiration(env, owner, spender); + let current_ledger = env.ledger().sequence(); + + if expiration <= current_ledger { + return 0; + } + + get_allowance(env, owner, spender) +} \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/balance.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/balance.rs new file mode 100644 index 000000000..71b32b899 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/balance.rs @@ -0,0 +1,31 @@ +use soroban_sdk::{Address, Env}; +use crate::helper::{get_balance, set_balance, get_frozen}; +use crate::errors::TokenError; + +pub fn transfer_balance(env: &Env, from: &Address, to: &Address, amount: &i128) -> Result<(), TokenError> { + if *amount <= 0 { + return Err(TokenError::InvalidAmount); + } + + if get_frozen(env, from) { + return Err(TokenError::AccountFrozen); + } + + if get_frozen(env, to) { + return Err(TokenError::AccountFrozen); + } + + let from_balance = get_balance(env, from); + if from_balance < *amount { + return Err(TokenError::InsufficientBalance); + } + + set_balance(env, from, &(from_balance - amount)); + + let to_balance = get_balance(env, to); + let new_balance = to_balance.checked_add(*amount) + .ok_or(TokenError::BalanceOverflow)?; + set_balance(env, to, &new_balance); + + Ok(()) +} \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/errors.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/errors.rs new file mode 100644 index 000000000..95def4928 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/errors.rs @@ -0,0 +1,23 @@ +use soroban_sdk::contracterror; + +#[contracterror] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +#[repr(u32)] +pub enum TokenError { + AlreadyInitialized = 1, + NameTooLong = 2, + SymbolTooLong = 3, + DecimalsTooHigh = 4, + InvalidTotalSupply = 5, + InvalidAmount = 6, + InsufficientBalance = 7, + InsufficientAllowance = 8, + AccountFrozen = 9, + InvalidExpiration = 10, + BalanceOverflow = 11, + SupplyOverflow = 12, + NotInitialized = 13, + Unauthorized = 14, + BalanceUnderflow = 15, + DecimalTooLong = 16, +} \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/helper.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/helper.rs new file mode 100644 index 000000000..91fc2438c --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/helper.rs @@ -0,0 +1,102 @@ +use soroban_sdk::{Address, Env, String}; +use crate::types::DataKey; + +pub fn set_admin(env: &Env, admin: &Address) { + env.storage().instance().set(&DataKey::Admin, admin); +} + +pub fn get_admin(env: &Env) -> Address { + env.storage().instance().get(&DataKey::Admin).unwrap() +} + +pub fn has_admin(env: &Env) -> bool { + env.storage().instance().has(&DataKey::Admin) +} + +pub fn set_balance(env: &Env, addr: &Address, amount: &i128) { + let key = DataKey::Balance(addr.clone()); + if *amount == 0 { + env.storage().persistent().remove(&key); + } else { + env.storage().persistent().set(&key, amount); + env.storage().persistent().extend_ttl(&key, 100, 100); + } +} + +pub fn get_balance(env: &Env, addr: &Address) -> i128 { + let key = DataKey::Balance(addr.clone()); + env.storage().persistent().get(&key).unwrap_or(0) +} + +pub fn set_allowance(env: &Env, owner: &Address, spender: &Address, amount: &i128) { + let key = DataKey::Allowance(owner.clone(), spender.clone()); + if *amount == 0 { + env.storage().persistent().remove(&key); + } else { + env.storage().persistent().set(&key, amount); + env.storage().persistent().extend_ttl(&key, 100, 100); + } +} + +pub fn get_allowance(env: &Env, owner: &Address, spender: &Address) -> i128 { + let key = DataKey::Allowance(owner.clone(), spender.clone()); + env.storage().persistent().get(&key).unwrap_or(0) +} + +pub fn set_allowance_expiration(env: &Env, owner: &Address, spender: &Address, expiration: &u32) { + let key = DataKey::AllowanceExpiration(owner.clone(), spender.clone()); + env.storage().persistent().set(&key, expiration); + env.storage().persistent().extend_ttl(&key, 100, 100); +} + +pub fn get_allowance_expiration(env: &Env, owner: &Address, spender: &Address) -> u32 { + let key = DataKey::AllowanceExpiration(owner.clone(), spender.clone()); + env.storage().persistent().get(&key).unwrap_or(0) +} + +pub fn set_frozen(env: &Env, addr: &Address, frozen: &bool) { + let key = DataKey::Frozen(addr.clone()); + if *frozen { + env.storage().persistent().set(&key, frozen); + env.storage().persistent().extend_ttl(&key, 100, 100); + } else { + env.storage().persistent().remove(&key); + } +} + +pub fn get_frozen(env: &Env, addr: &Address) -> bool { + let key = DataKey::Frozen(addr.clone()); + env.storage().persistent().get(&key).unwrap_or(false) +} + +pub fn set_name(env: &Env, name: &String) { + env.storage().instance().set(&DataKey::Name, name); +} + +pub fn get_name(env: &Env) -> String { + env.storage().instance().get(&DataKey::Name).unwrap() +} + +pub fn set_symbol(env: &Env, symbol: &String) { + env.storage().instance().set(&DataKey::Symbol, symbol); +} + +pub fn get_symbol(env: &Env) -> String { + env.storage().instance().get(&DataKey::Symbol).unwrap() +} + +pub fn set_decimals(env: &Env, decimals: &u32) { + env.storage().instance().set(&DataKey::Decimals, decimals); +} + +pub fn get_decimals(env: &Env) -> u32 { + env.storage().instance().get(&DataKey::Decimals).unwrap() +} + +pub fn set_total_supply(env: &Env, total_supply: &i128) { + env.storage().instance().set(&DataKey::TotalSupply, total_supply); +} + +pub fn get_total_supply(env: &Env) -> i128 { + env.storage().instance().get(&DataKey::TotalSupply).unwrap() +} diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/lib.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/lib.rs new file mode 100644 index 000000000..53d28b5e2 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/lib.rs @@ -0,0 +1,15 @@ +#![no_std] + +mod errors; +mod import; +mod events; +mod helpers; +mod metadata; +mod traits; +mod types; +mod admin; +mod allowance; +mod Sep_41; +mod test; + +pub use Sep_41::*; \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/metadata.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/metadata.rs new file mode 100644 index 000000000..fcfae5495 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/metadata.rs @@ -0,0 +1,28 @@ +use soroban_sdk::{Env, String}; +use crate::helper::{get_name, get_symbol, get_decimals, get_total_supply}; +use crate::errors::TokenError; + +pub fn get_token_info(env: &Env) -> (String, String, u32, i128) { + ( + get_name(env), + get_symbol(env), + get_decimals(env), + get_total_supply(env), + ) +} + +pub fn validate_metadata(name: &String, symbol: &String, decimals: &u32) -> Result<(), TokenError> { + if name.len() > 32 { + return Err(TokenError::NameTooLong); + } + + if symbol.len() > 16 { + return Err(TokenError::SymbolTooLong); + } + + if *decimals > 18 { + return Err(TokenError::DecimalsTooHigh); + } + + Ok(()) +} \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/sep_41.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/sep_41.rs new file mode 100644 index 000000000..c15f4a3c8 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/sep_41.rs @@ -0,0 +1,306 @@ +#![no_std] +use soroban_sdk::{contract, contractimpl, contractmeta, panic_with_error, Address, Env, String}; + +pub mod admin; +pub mod allowance; +pub mod balance; +pub mod metadata; +pub mod helper; +pub mod types; +pub mod traits; +pub mod errors; + +pub use admin::*; +pub use allowance::*; +pub use balance::*; +pub use metadata::*; +pub use helper::*; +pub use types::*; +pub use traits::*; +pub use errors::*; + +contractmeta!( + key = "Description", + val = "SEP-41 Compliant Token Contract" +); + +contractmeta!( + key = "version", + val = "1.0.0" +); + +#[contract] +pub struct Token; + +#[contractimpl] +impl Token { + pub fn initialize( + env: Env, + admin: Address, + name: String, + symbol: String, + decimals: u32, + total_supply: i128, + ) -> Result<(), TokenError> { + if has_admin(&env) { + return Err(TokenError::AlreadyInitialized); + } + + admin.require_auth(); + + if name.len() > 32 { + return Err(TokenError::NameTooLong); + } + + if symbol.len() > 16 { + return Err(TokenError::SymbolTooLong); + } + + if decimals > 18 { + return Err(TokenError::DecimalsTooHigh); + } + + if total_supply < 0 { + return Err(TokenError::InvalidTotalSupply); + } + + set_admin(&env, &admin); + set_name(&env, &name); + set_symbol(&env, &symbol); + set_decimals(&env, &decimals); + set_total_supply(&env, &total_supply); + + if total_supply > 0 { + set_balance(&env, &admin, &total_supply); + } + + Ok(()) + } + + pub fn transfer(env: Env, from: Address, to: Address, amount: i128) -> Result<(), TokenError> { + from.require_auth(); + Self::transfer_impl(&env, &from, &to, &amount) + } + + pub fn transfer_from(env: Env, spender: Address, from: Address, to: Address, amount: i128) -> Result<(), TokenError> { + spender.require_auth(); + + let allowance = get_allowance(&env, &from, &spender); + if allowance < amount { + return Err(TokenError::InsufficientAllowance); + } + + set_allowance(&env, &from, &spender, &(allowance - amount)); + Self::transfer_impl(&env, &from, &to, &amount) + } + + fn transfer_impl(env: &Env, from: &Address, to: &Address, amount: &i128) -> Result<(), TokenError> { + if *amount < 0 { + return Err(TokenError::InvalidAmount); + } + + if *amount == 0 { + return Ok(()); + } + + if from == to { + return Ok(()); + } + + if get_frozen(env, from) { + return Err(TokenError::AccountFrozen); + } + + if get_frozen(env, to) { + return Err(TokenError::AccountFrozen); + } + + let from_balance = get_balance(env, from); + if from_balance < *amount { + return Err(TokenError::InsufficientBalance); + } + + set_balance(env, from, &(from_balance - amount)); + let to_balance = get_balance(env, to); + let new_to_balance = to_balance.checked_add(*amount) + .ok_or(TokenError::BalanceOverflow)?; + set_balance(env, to, &new_to_balance); + + Ok(()) + } + + pub fn balance(env: Env, id: Address) -> i128 { + get_balance(&env, &id) + } + + pub fn approve( + env: Env, + from: Address, + spender: Address, + amount: i128, + expiration_ledger: u32, + ) -> Result<(), TokenError> { + from.require_auth(); + + if amount < 0 { + return Err(TokenError::InvalidAmount); + } + + let current_ledger = env.ledger().sequence(); + if expiration_ledger <= current_ledger { + return Err(TokenError::InvalidExpiration); + } + + set_allowance(&env, &from, &spender, &amount); + set_allowance_expiration(&env, &from, &spender, &expiration_ledger); + + Ok(()) + } + + pub fn allowance(env: Env, from: Address, spender: Address) -> i128 { + let expiration = get_allowance_expiration(&env, &from, &spender); + let current_ledger = env.ledger().sequence(); + + if expiration <= current_ledger { + return 0; + } + + get_allowance(&env, &from, &spender) + } + + pub fn mint(env: Env, to: Address, amount: i128) -> Result<(), TokenError> { + if !has_admin(&env) { + return Err(TokenError::NotInitialized); + } + + let admin = get_admin(&env); + admin.require_auth(); + + if amount < 0 { + return Err(TokenError::InvalidAmount); + } + + if amount == 0 { + return Ok(()); + } + + if get_frozen(&env, &to) { + return Err(TokenError::AccountFrozen); + } + + let to_balance = get_balance(&env, &to); + let new_balance = to_balance.checked_add(amount) + .ok_or(TokenError::BalanceOverflow)?; + + set_balance(&env, &to, &new_balance); + + let total_supply = get_total_supply(&env); + let new_supply = total_supply.checked_add(amount) + .ok_or(TokenError::SupplyOverflow)?; + + set_total_supply(&env, &new_supply); + + Ok(()) + } + + pub fn burn(env: Env, from: Address, amount: i128) -> Result<(), TokenError> { + from.require_auth(); + Self::burn_impl(&env, &from, &amount) + } + + pub fn burn_from(env: Env, spender: Address, from: Address, amount: i128) -> Result<(), TokenError> { + spender.require_auth(); + + let allowance = get_allowance(&env, &from, &spender); + if allowance < amount { + return Err(TokenError::InsufficientAllowance); + } + + set_allowance(&env, &from, &spender, &(allowance - amount)); + Self::burn_impl(&env, &from, &amount) + } + + fn burn_impl(env: &Env, from: &Address, amount: &i128) -> Result<(), TokenError> { + if *amount < 0 { + return Err(TokenError::InvalidAmount); + } + + if *amount == 0 { + return Ok(()); + } + + let from_balance = get_balance(env, from); + if from_balance < *amount { + return Err(TokenError::InsufficientBalance); + } + + set_balance(env, from, &(from_balance - amount)); + + let total_supply = get_total_supply(env); + set_total_supply(env, &(total_supply - amount)); + + Ok(()) + } + + pub fn set_admin(env: Env, new_admin: Address) -> Result<(), TokenError> { + if !has_admin(&env) { + return Err(TokenError::NotInitialized); + } + + let admin = get_admin(&env); + admin.require_auth(); + set_admin(&env, &new_admin); + + Ok(()) + } + + pub fn admin(env: Env) -> Address { + if !has_admin(&env) { + panic_with_error!(&env, TokenError::NotInitialized); + } + + get_admin(&env) + } + + pub fn name(env: Env) -> String { + get_name(&env) + } + + pub fn symbol(env: Env) -> String { + get_symbol(&env) + } + + pub fn decimals(env: Env) -> u32 { + get_decimals(&env) + } + + pub fn total_supply(env: Env) -> i128 { + get_total_supply(&env) + } + + pub fn freeze_account(env: Env, account: Address) { + if !has_admin(&env) { + panic_with_error!(&env, TokenError::NotInitialized); + } + + let admin = get_admin(&env); + admin.require_auth(); + set_frozen(&env, &account, &true); + } + + pub fn unfreeze_account(env: Env, account: Address) { + if !has_admin(&env) { + panic_with_error!(&env, TokenError::NotInitialized); + } + + let admin = get_admin(&env); + admin.require_auth(); + set_frozen(&env, &account, &false); + } + + pub fn is_frozen(env: Env, account: Address) -> bool { + get_frozen(&env, &account) + } +} + +mod test; \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/test.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/test.rs new file mode 100644 index 000000000..379286d60 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/test.rs @@ -0,0 +1,220 @@ +#![cfg(test)] + +use super::*; + use soroban_sdk::{testutils::Address as _, Address, Env, String}; + + fn create_token_contract(e: &Env, admin: &Address) -> Address { + e.register_contract(None, Token {}) + } + + #[test] + fn test_initialize() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + assert_eq!(client.name(), name); + assert_eq!(client.symbol(), symbol); + assert_eq!(client.decimals(), decimals); + assert_eq!(client.total_supply(), total_supply); + assert_eq!(client.admin(), admin); + assert_eq!(client.balance(&admin), total_supply); + } + + #[test] + fn test_transfer() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let user1 = Address::generate(&env); + let user2 = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + let transfer_amount = 100000i128; + client.transfer(&admin, &user1, &transfer_amount); + + assert_eq!(client.balance(&admin), total_supply - transfer_amount); + assert_eq!(client.balance(&user1), transfer_amount); + + let transfer_amount2 = 50000i128; + client.transfer(&user1, &user2, &transfer_amount2); + + assert_eq!(client.balance(&user1), transfer_amount - transfer_amount2); + assert_eq!(client.balance(&user2), transfer_amount2); + } + + #[test] + fn test_approve_and_transfer_from() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let owner = Address::generate(&env); + let spender = Address::generate(&env); + let recipient = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + let owner_amount = 100000i128; + client.transfer(&admin, &owner, &owner_amount); + + let allowance_amount = 50000i128; + let expiration = env.ledger().sequence() + 100; + client.approve(&owner, &spender, &allowance_amount, &expiration); + + assert_eq!(client.allowance(&owner, &spender), allowance_amount); + + let transfer_amount = 30000i128; + client.transfer_from(&spender, &owner, &recipient, &transfer_amount); + + assert_eq!(client.balance(&owner), owner_amount - transfer_amount); + assert_eq!(client.balance(&recipient), transfer_amount); + assert_eq!(client.allowance(&owner, &spender), allowance_amount - transfer_amount); + } + + #[test] + fn test_mint() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let user = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + let mint_amount = 500000i128; + client.mint(&user, &mint_amount); + + assert_eq!(client.balance(&user), mint_amount); + assert_eq!(client.total_supply(), total_supply + mint_amount); + } + + #[test] + fn test_burn() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let user = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + let user_amount = 100000i128; + client.transfer(&admin, &user, &user_amount); + + let burn_amount = 50000i128; + client.burn(&user, &burn_amount); + + assert_eq!(client.balance(&user), user_amount - burn_amount); + assert_eq!(client.total_supply(), total_supply - burn_amount); + } + + #[test] + fn test_freeze_account() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let user = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + client.freeze_account(&user); + assert_eq!(client.is_frozen(&user), true); + + client.unfreeze_account(&user); + assert_eq!(client.is_frozen(&user), false); + } + + #[test] + #[should_panic(expected = "Already initialized")] + fn test_double_initialize() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + } + + #[test] + #[should_panic(expected = "Insufficient balance")] + fn test_insufficient_balance() { + let env = Env::default(); + env.mock_all_auths(); + + let admin = Address::generate(&env); + let user = Address::generate(&env); + + let token = create_token_contract(&env, &admin); + let client = TokenClient::new(&env, &token); + + let name = String::from_str(&env, "Test Token"); + let symbol = String::from_str(&env, "TEST"); + let decimals = 7u32; + let total_supply = 1000000i128; + + client.initialize(&admin, &name, &symbol, &decimals, &total_supply); + + client.transfer(&user, &admin, &1000i128); + } \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/traits.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/traits.rs new file mode 100644 index 000000000..8091aed80 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/traits.rs @@ -0,0 +1,57 @@ +use soroban_sdk::{Address, Env}; +use crate::helper::get_admin; +use crate::errors::TokenError; + +pub trait AdminCheck { + fn require_admin(&self, env: &Env); +} + +impl AdminCheck for Address { + fn require_admin(&self, env: &Env) { + let admin = get_admin(env); + if *self != admin { + panic!("Unauthorized"); + } + } +} + +pub trait TokenValidation { + fn validate_positive_amount(&self); + fn validate_non_zero(&self); +} + +impl TokenValidation for i128 { + fn validate_positive_amount(&self) { + if *self < 0 { + panic!("Invalid amount"); + } + } + + fn validate_non_zero(&self) { + if *self == 0 { + panic!("Balance underflow"); + } + } +} + +pub fn require_admin_result(addr: &Address, env: &Env) -> Result<(), TokenError> { + let admin = get_admin(env); + if *addr != admin { + return Err(TokenError::Unauthorized); + } + Ok(()) +} + +pub fn validate_positive_amount_result(amount: &i128) -> Result<(), TokenError> { + if *amount < 0 { + return Err(TokenError::InvalidAmount); + } + Ok(()) +} + +pub fn validate_non_zero_result(amount: &i128) -> Result<(), TokenError> { + if *amount == 0 { + return Err(TokenError::BalanceUnderflow); + } + Ok(()) +} \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/types.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/types.rs new file mode 100644 index 000000000..71b3b31de --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/Sep_41/src/types.rs @@ -0,0 +1,22 @@ +use soroban_sdk::{contracttype, Address}; + +#[derive(Clone)] +#[contracttype] +pub enum DataKey { + Admin, + Name, + Symbol, + Decimals, + TotalSupply, + Balance(Address), + Allowance(Address, Address), + AllowanceExpiration(Address, Address), + Frozen(Address), +} + +#[derive(Clone)] +#[contracttype] +pub struct AllowanceData { + pub amount: i128, + pub expiration_ledger: u32, +} diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/Cargo.toml b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/Cargo.toml new file mode 100644 index 000000000..abbf78ae2 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "employee_management" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["lib", "cdylib"] +doctest = false + +[dependencies] +soroban-sdk = { workspace = true } + +[dev-dependencies] +soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/Makefile b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/Makefile new file mode 100644 index 000000000..b9719346b --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/Makefile @@ -0,0 +1,16 @@ +default: build + +all: test + +test: build + cargo test + +build: + stellar contract build + @ls -l target/wasm32v1-none/release/*.wasm + +fmt: + cargo fmt --all + +clean: + cargo clean diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/deploy.sh b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/deploy.sh new file mode 100644 index 000000000..6ff0a5816 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/deploy.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +# Employee Management System Deployment Script +# Make sure you have soroban CLI installed and configured + +echo " Starting Employee Management System Deployment..." + + +NETWORK="testnet" +IDENTITY="default" + +echo "Building contracts..." +cd contracts/Sep_41 +soroban contract build +cd ../employee_management +soroban contract build +cd ../.. + +echo " Deploying SEP-41 Token Contract..." +TOKEN_CONTRACT_ID=$(soroban contract deploy \ + --wasm contracts/Sep_41/target/wasm32-unknown-unknown/release/sep_41.wasm \ + --network $NETWORK \ + --source $IDENTITY) + +echo "Token Contract deployed at: $TOKEN_CONTRACT_ID" + +echo " Deploying Employee Management Contract..." +EMPLOYEE_CONTRACT_ID=$(soroban contract deploy \ + --wasm contracts/employee_management/target/wasm32-unknown-unknown/release/employee_management.wasm \ + --network $NETWORK \ + --source $IDENTITY) + +echo "Employee Management Contract deployed at: $EMPLOYEE_CONTRACT_ID" + +echo "🔧 Initializing Token Contract..." +ADMIN_ADDRESS=$(soroban keys address $IDENTITY) + +soroban contract invoke \ + --id $TOKEN_CONTRACT_ID \ + --network $NETWORK \ + --source $IDENTITY \ + -- initialize \ + --admin $ADMIN_ADDRESS \ + --name "Company Token" \ + --symbol "COMP" \ + --decimals 7 \ + --total_supply 1000000000000000 + + +echo " Initializing Employee Management Contract..." +soroban contract invoke \ + --id $EMPLOYEE_CONTRACT_ID \ + --network $NETWORK \ + --source $IDENTITY \ + -- initialize \ + --admin $ADMIN_ADDRESS \ + --token_contract $TOKEN_CONTRACT_ID + +echo " Deployment completed!" +echo " Contract Addresses:" +echo " Token Contract: $TOKEN_CONTRACT_ID" +echo " Employee Management: $EMPLOYEE_CONTRACT_ID" +echo " Admin: $ADMIN_ADDRESS" + +cat > contract_addresses.txt << EOF +TOKEN_CONTRACT_ID=$TOKEN_CONTRACT_ID +EMPLOYEE_CONTRACT_ID=$EMPLOYEE_CONTRACT_ID +ADMIN_ADDRESS=$ADMIN_ADDRESS +NETWORK=$NETWORK +EOF + +echo " Contract addresses saved to contract_addresses.txt" + +echo " Would you like to register a sample institution? (y/n)" +read -r REGISTER_SAMPLE + +if [ "$REGISTER_SAMPLE" = "y" ] || [ "$REGISTER_SAMPLE" = "Y" ]; then + INSTITUTION_ADDRESS=$(soroban keys address $IDENTITY) + + soroban contract invoke \ + --id $EMPLOYEE_CONTRACT_ID \ + --network $NETWORK \ + --source $IDENTITY \ + -- register_institution \ + --institution_address $INSTITUTION_ADDRESS \ + --name "Sample Tech Corp" \ + --admin $ADMIN_ADDRESS + + echo "✅ Sample institution registered!" + echo " Institution Address: $INSTITUTION_ADDRESS" +fi + +echo "🎉 Setup complete! You can now interact with your Employee Management System." \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/employee_contract.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/employee_contract.rs new file mode 100644 index 000000000..498961bdc --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/employee_contract.rs @@ -0,0 +1,394 @@ +use soroban_sdk::{ + contract, contractimpl, contractmeta, contracttype, + Address, Env, String +}; + +use crate::imports::sep_41::Client as Sep41Client; +use crate::errors::EmployeeError; + +contractmeta!( + key = "Description", + val = "Employee Management System with SEP-41 Token Integration" +); + +contractmeta!( + key = "version", + val = "1.0.0" +); + +#[derive(Clone)] +#[contracttype] +pub enum DataKey { + Admin, + TokenContract, + Employee(Address), + Institution(Address), + EmployeeCount, + NextEmployeeId, +} + +#[derive(Clone, PartialEq, Debug)] +#[contracttype] +pub enum EmployeeRank { + Intern = 1, + Junior = 2, + Mid = 3, + Senior = 4, + Lead = 5, + Manager = 6, + Director = 7, + VP = 8, + CEO = 9, +} + +#[derive(Clone, PartialEq, Debug)] +#[contracttype] +pub enum EmployeeStatus { + Active, + Suspended, + Terminated, +} + +#[derive(Clone)] +#[contracttype] +pub struct Employee { + pub id: u64, + pub address: Address, + pub institution: Address, + pub name: String, + pub rank: EmployeeRank, + pub salary: i128, + pub status: EmployeeStatus, + pub hire_date: u64, + pub last_promotion: Option, +} + +#[derive(Clone)] +#[contracttype] +pub struct Institution { + pub address: Address, + pub name: String, + pub admin: Address, + pub employee_count: u32, + pub is_active: bool, +} + +#[contract] +pub struct EmployeeManagement; + +#[contractimpl] +impl EmployeeManagement { + pub fn initialize( + env: Env, + admin: Address, + token_contract: Address, + ) -> Result<(), EmployeeError> { + if Self::has_admin(&env) { + return Err(EmployeeError::AlreadyInitialized); + } + + admin.require_auth(); + + env.storage().instance().set(&DataKey::Admin, &admin); + env.storage().instance().set(&DataKey::TokenContract, &token_contract); + env.storage().instance().set(&DataKey::EmployeeCount, &0u32); + env.storage().instance().set(&DataKey::NextEmployeeId, &1u64); + + Ok(()) + } + + pub fn register_institution( + env: Env, + institution_address: Address, + name: String, + admin: Address, + ) -> Result<(), EmployeeError> { + Self::require_admin(&env)?; + + if name.len() > 50 { + return Err(EmployeeError::InvalidRank); + } + + let institution = Institution { + address: institution_address.clone(), + name, + admin, + employee_count: 0, + is_active: true, + }; + + env.storage().persistent().set(&DataKey::Institution(institution_address.clone()), &institution); + env.storage().persistent().extend_ttl(&DataKey::Institution(institution_address), 100, 100); + + Ok(()) + } + + pub fn add_employee( + env: Env, + employee_address: Address, + institution: Address, + name: String, + rank: EmployeeRank, + salary: i128, + ) -> Result { + let inst_data = Self::get_institution(&env, institution.clone())?; + inst_data.admin.require_auth(); + + if !inst_data.is_active { + return Err(EmployeeError::InstitutionNotActive); + } + + if env.storage().persistent().has(&DataKey::Employee(employee_address.clone())) { + return Err(EmployeeError::EmployeeAlreadyExists); + } + + if salary <= 0 { + return Err(EmployeeError::InvalidSalary); + } + + if name.len() > 50 { + return Err(EmployeeError::InvalidRank); + } + + let employee_id = env.storage().instance().get(&DataKey::NextEmployeeId).unwrap_or(1u64); + let current_time = env.ledger().timestamp(); + + let employee = Employee { + id: employee_id, + address: employee_address.clone(), + institution: institution.clone(), + name, + rank, + salary, + status: EmployeeStatus::Active, + hire_date: current_time, + last_promotion: None, + }; + + env.storage().persistent().set(&DataKey::Employee(employee_address.clone()), &employee); + env.storage().persistent().extend_ttl(&DataKey::Employee(employee_address), 100, 100); + + env.storage().instance().set(&DataKey::NextEmployeeId, &(employee_id + 1)); + + let mut updated_inst = inst_data; + updated_inst.employee_count += 1; + env.storage().persistent().set(&DataKey::Institution(institution.clone()), &updated_inst); + env.storage().persistent().extend_ttl(&DataKey::Institution(institution), 100, 100); + + let total_count: u32 = env.storage().instance().get(&DataKey::EmployeeCount).unwrap_or(0); + env.storage().instance().set(&DataKey::EmployeeCount, &(total_count + 1)); + + Ok(employee_id) + } + + pub fn update_employee( + env: Env, + employee_address: Address, + name: Option, + salary: Option, + ) -> Result<(), EmployeeError> { + let mut employee = Self::get_employee(&env, employee_address.clone())?; + + let inst_data = Self::get_institution(&env, employee.institution.clone())?; + inst_data.admin.require_auth(); + + if let Some(new_name) = name { + if new_name.len() > 50 { + return Err(EmployeeError::InvalidRank); + } + employee.name = new_name; + } + + if let Some(new_salary) = salary { + if new_salary <= 0 { + return Err(EmployeeError::InvalidSalary); + } + employee.salary = new_salary; + } + + env.storage().persistent().set(&DataKey::Employee(employee_address.clone()), &employee); + env.storage().persistent().extend_ttl(&DataKey::Employee(employee_address), 100, 100); + + Ok(()) + } + + pub fn promote_employee( + env: Env, + employee_address: Address, + new_rank: EmployeeRank, + new_salary: i128, + ) -> Result<(), EmployeeError> { + let mut employee = Self::get_employee(&env, employee_address.clone())?; + + let inst_data = Self::get_institution(&env, employee.institution.clone())?; + inst_data.admin.require_auth(); + + if employee.status != EmployeeStatus::Active { + return Err(EmployeeError::EmployeeNotActive); + } + + let current_rank_value = employee.rank.clone() as u32; + let new_rank_value = new_rank.clone() as u32; + + if new_rank_value <= current_rank_value { + return Err(EmployeeError::InvalidRank); + } + + if new_salary <= employee.salary { + return Err(EmployeeError::InvalidSalary); + } + + employee.rank = new_rank; + employee.salary = new_salary; + employee.last_promotion = Some(env.ledger().timestamp()); + + env.storage().persistent().set(&DataKey::Employee(employee_address.clone()), &employee); + env.storage().persistent().extend_ttl(&DataKey::Employee(employee_address), 100, 100); + + Ok(()) + } + + pub fn suspend_employee( + env: Env, + employee_address: Address, + ) -> Result<(), EmployeeError> { + let mut employee = Self::get_employee(&env, employee_address.clone())?; + + let inst_data = Self::get_institution(&env, employee.institution.clone())?; + inst_data.admin.require_auth(); + + if employee.status != EmployeeStatus::Active { + return Err(EmployeeError::EmployeeAlreadySuspended); + } + + employee.status = EmployeeStatus::Suspended; + + env.storage().persistent().set(&DataKey::Employee(employee_address.clone()), &employee); + env.storage().persistent().extend_ttl(&DataKey::Employee(employee_address), 100, 100); + + Ok(()) + } + + pub fn reactivate_employee( + env: Env, + employee_address: Address, + ) -> Result<(), EmployeeError> { + let mut employee = Self::get_employee(&env, employee_address.clone())?; + + let inst_data = Self::get_institution(&env, employee.institution.clone())?; + inst_data.admin.require_auth(); + + if employee.status != EmployeeStatus::Suspended { + return Err(EmployeeError::EmployeeNotActive); + } + + employee.status = EmployeeStatus::Active; + + env.storage().persistent().set(&DataKey::Employee(employee_address.clone()), &employee); + env.storage().persistent().extend_ttl(&DataKey::Employee(employee_address), 100, 100); + + Ok(()) + } + + pub fn remove_employee( + env: Env, + employee_address: Address, + ) -> Result<(), EmployeeError> { + let mut employee = Self::get_employee(&env, employee_address.clone())?; + + let inst_data = Self::get_institution(&env, employee.institution.clone())?; + inst_data.admin.require_auth(); + + employee.status = EmployeeStatus::Terminated; + + let mut updated_inst = inst_data; + if updated_inst.employee_count > 0 { + updated_inst.employee_count -= 1; + } + env.storage().persistent().set(&DataKey::Institution(employee.institution.clone()), &updated_inst); + env.storage().persistent().extend_ttl(&DataKey::Institution(employee.institution.clone()), 100, 100); + + let total_count: u32 = env.storage().instance().get(&DataKey::EmployeeCount).unwrap_or(0); + if total_count > 0 { + env.storage().instance().set(&DataKey::EmployeeCount, &(total_count - 1)); + } + + env.storage().persistent().set(&DataKey::Employee(employee_address.clone()), &employee); + env.storage().persistent().extend_ttl(&DataKey::Employee(employee_address), 100, 100); + + Ok(()) + } + + pub fn pay_salary( + env: Env, + employee_address: Address, + ) -> Result<(), EmployeeError> { + let employee = Self::get_employee(&env, employee_address.clone())?; + + let inst_data = Self::get_institution(&env, employee.institution.clone())?; + inst_data.admin.require_auth(); + + if employee.status != EmployeeStatus::Active { + return Err(EmployeeError::EmployeeNotActive); + } + + let token_contract_address = Self::get_token_contract(&env)?; + + let sep41_client = Sep41Client::new(&env, &token_contract_address); + + match sep41_client.try_transfer(&employee.institution, &employee.address, &employee.salary) { + Ok(_) => Ok(()), + Err(_) => Err(EmployeeError::TokenError), + } + } + + pub fn get_employee(env: &Env, employee_address: Address) -> Result { + env.storage() + .persistent() + .get(&DataKey::Employee(employee_address)) + .ok_or(EmployeeError::EmployeeNotFound) + } + + pub fn get_institution(env: &Env, institution_address: Address) -> Result { + env.storage() + .persistent() + .get(&DataKey::Institution(institution_address)) + .ok_or(EmployeeError::InstitutionNotFound) + } + + pub fn view_employee(env: Env, employee_address: Address) -> Result { + Self::get_employee(&env, employee_address) + } + + pub fn view_institution(env: Env, institution_address: Address) -> Result { + Self::get_institution(&env, institution_address) + } + + pub fn get_employee_count(env: Env) -> u32 { + env.storage().instance().get(&DataKey::EmployeeCount).unwrap_or(0) + } + + pub fn get_admin(env: Env) -> Result { + env.storage() + .instance() + .get(&DataKey::Admin) + .ok_or(EmployeeError::NotInitialized) + } + + pub fn get_token_contract(env: &Env) -> Result { + env.storage() + .instance() + .get(&DataKey::TokenContract) + .ok_or(EmployeeError::NotInitialized) + } + + fn has_admin(env: &Env) -> bool { + env.storage().instance().has(&DataKey::Admin) + } + + fn require_admin(env: &Env) -> Result<(), EmployeeError> { + let admin = Self::get_admin(env.clone())?; + admin.require_auth(); + Ok(()) + } +} \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/errors.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/errors.rs new file mode 100644 index 000000000..edfe61434 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/errors.rs @@ -0,0 +1,23 @@ +use soroban_sdk::contracterror; + +#[contracterror] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +#[repr(u32)] +pub enum EmployeeError { + NotInitialized = 1, + AlreadyInitialized = 2, + Unauthorized = 3, + EmployeeNotFound = 4, + InstitutionNotFound = 5, + EmployeeAlreadyExists = 6, + InstitutionNotActive = 7, + InvalidSalary = 8, + InvalidRank = 9, + EmployeeAlreadySuspended = 10, + EmployeeNotActive = 11, + InsufficientFunds = 12, + TokenError = 13, +} + + + diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/imports.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/imports.rs new file mode 100644 index 000000000..6546c5657 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/imports.rs @@ -0,0 +1,5 @@ +pub mod sep_41 { + use soroban_sdk::contractimport; + contractimport!(file = "../../target/wasm32v1-none/release/Sep_41.wasm"); +} + diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/lib.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/lib.rs new file mode 100644 index 000000000..33af7319b --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/lib.rs @@ -0,0 +1,12 @@ +#![no_std] + +mod employee_contract; +pub mod errors; + +mod imports; + +#[cfg(test)] +mod test; + +pub use employee_contract::*; +pub use errors::*; diff --git a/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/test.rs b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/test.rs new file mode 100644 index 000000000..7a3d65917 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/Employment_Management_System/contracts/employee_management/src/test.rs @@ -0,0 +1,315 @@ +#![cfg(test)] + +use soroban_sdk::{testutils::Address as _, Address, Env, String}; + +use crate::{ + EmployeeManagement, + EmployeeManagementClient, + EmployeeRank, + EmployeeStatus +}; + +#[test] +fn test_initialize() { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(EmployeeManagement, ()); + let client = EmployeeManagementClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let token_contract = Address::generate(&env); + + let result = client.try_initialize(&admin, &token_contract); + assert!(result.is_ok()); + + let stored_admin = client.get_admin(); + assert_eq!(stored_admin, admin); +} + +#[test] +fn test_register_institution() { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(EmployeeManagement, ()); + let client = EmployeeManagementClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let token_contract = Address::generate(&env); + let institution_addr = Address::generate(&env); + let inst_admin = Address::generate(&env); + + client.initialize(&admin, &token_contract); + + let result = client.try_register_institution( + &institution_addr, + &String::from_str(&env, "Tech Corp"), + &inst_admin + ); + assert!(result.is_ok()); + + let institution = client.view_institution(&institution_addr); + assert_eq!(institution.name, String::from_str(&env, "Tech Corp")); + assert_eq!(institution.admin, inst_admin); +} + +#[test] +fn test_add_employee() { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(EmployeeManagement, ()); + let client = EmployeeManagementClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let token_contract = Address::generate(&env); + let institution_addr = Address::generate(&env); + let inst_admin = Address::generate(&env); + let employee_addr = Address::generate(&env); + + client.initialize(&admin, &token_contract); + client.register_institution( + &institution_addr, + &String::from_str(&env, "Tech Corp"), + &inst_admin + ); + + let employee_id = client.add_employee( + &employee_addr, + &institution_addr, + &String::from_str(&env, "John Doe"), + &EmployeeRank::Junior, + &50000i128 + ); + assert!(employee_id > 0); + + let employee = client.view_employee(&employee_addr); + assert_eq!(employee.name, String::from_str(&env, "John Doe")); + assert_eq!(employee.rank, EmployeeRank::Junior); + assert_eq!(employee.salary, 50000i128); +} + +#[test] +fn test_promote_employee() { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(EmployeeManagement, ()); + let client = EmployeeManagementClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let token_contract = Address::generate(&env); + let institution_addr = Address::generate(&env); + let inst_admin = Address::generate(&env); + let employee_addr = Address::generate(&env); + + client.initialize(&admin, &token_contract); + client.register_institution( + &institution_addr, + &String::from_str(&env, "Tech Corp"), + &inst_admin + ); + client.add_employee( + &employee_addr, + &institution_addr, + &String::from_str(&env, "John Doe"), + &EmployeeRank::Junior, + &40000i128 + ); + + let result = client.try_promote_employee( + &employee_addr, + &EmployeeRank::Mid, + &55000i128 + ); + assert!(result.is_ok()); + + let employee = client.view_employee(&employee_addr); + assert_eq!(employee.rank, EmployeeRank::Mid); + assert_eq!(employee.salary, 55000i128); +} + +#[test] +fn test_suspend_and_reactivate_employee() { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(EmployeeManagement, ()); + let client = EmployeeManagementClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let token_contract = Address::generate(&env); + let institution_addr = Address::generate(&env); + let inst_admin = Address::generate(&env); + let employee_addr = Address::generate(&env); + + client.initialize(&admin, &token_contract); + client.register_institution( + &institution_addr, + &String::from_str(&env, "Tech Corp"), + &inst_admin + ); + client.add_employee( + &employee_addr, + &institution_addr, + &String::from_str(&env, "John Doe"), + &EmployeeRank::Junior, + &40000i128 + ); + + let result = client.try_suspend_employee(&employee_addr); + assert!(result.is_ok()); + + let employee = client.view_employee(&employee_addr); + assert_eq!(employee.status, EmployeeStatus::Suspended); + + let result = client.try_reactivate_employee(&employee_addr); + assert!(result.is_ok()); + + let employee = client.view_employee(&employee_addr); + assert_eq!(employee.status, EmployeeStatus::Active); +} + +#[test] +fn test_update_employee() { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(EmployeeManagement, ()); + let client = EmployeeManagementClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let token_contract = Address::generate(&env); + let institution_addr = Address::generate(&env); + let inst_admin = Address::generate(&env); + let employee_addr = Address::generate(&env); + + client.initialize(&admin, &token_contract); + client.register_institution( + &institution_addr, + &String::from_str(&env, "Tech Corp"), + &inst_admin + ); + client.add_employee( + &employee_addr, + &institution_addr, + &String::from_str(&env, "John Doe"), + &EmployeeRank::Junior, + &40000i128 + ); + + let result = client.try_update_employee( + &employee_addr, + &Some(String::from_str(&env, "John Smith")), + &Some(45000i128) + ); + assert!(result.is_ok()); + + let employee = client.view_employee(&employee_addr); + assert_eq!(employee.name, String::from_str(&env, "John Smith")); + assert_eq!(employee.salary, 45000i128); +} + +#[test] +fn test_employee_count() { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(EmployeeManagement, ()); + let client = EmployeeManagementClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let token_contract = Address::generate(&env); + let institution_addr = Address::generate(&env); + let inst_admin = Address::generate(&env); + + client.initialize(&admin, &token_contract); + client.register_institution( + &institution_addr, + &String::from_str(&env, "Tech Corp"), + &inst_admin + ); + + assert_eq!(client.get_employee_count(), 0); + + let employee1 = Address::generate(&env); + let employee2 = Address::generate(&env); + + client.add_employee( + &employee1, + &institution_addr, + &String::from_str(&env, "Employee 1"), + &EmployeeRank::Junior, + &40000i128 + ); + + client.add_employee( + &employee2, + &institution_addr, + &String::from_str(&env, "Employee 2"), + &EmployeeRank::Mid, + &50000i128 + ); + + assert_eq!(client.get_employee_count(), 2); +} + +#[test] +fn test_unauthorized_access() { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(EmployeeManagement, ()); + let client = EmployeeManagementClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let token_contract = Address::generate(&env); + let institution_addr = Address::generate(&env); + let inst_admin = Address::generate(&env); + let _unauthorized_user = Address::generate(&env); + + client.initialize(&admin, &token_contract); + client.register_institution( + &institution_addr, + &String::from_str(&env, "Tech Corp"), + &inst_admin + ); + + +} + +#[test] +fn test_invalid_salary() { + let env = Env::default(); + env.mock_all_auths(); + + let contract_id = env.register(EmployeeManagement, ()); + let client = EmployeeManagementClient::new(&env, &contract_id); + + let admin = Address::generate(&env); + let token_contract = Address::generate(&env); + let institution_addr = Address::generate(&env); + let inst_admin = Address::generate(&env); + let employee_addr = Address::generate(&env); + + client.initialize(&admin, &token_contract); + client.register_institution( + &institution_addr, + &String::from_str(&env, "Tech Corp"), + &inst_admin + ); + + + let employee_id = client.add_employee( + &employee_addr, + &institution_addr, + &String::from_str(&env, "John Doe"), + &EmployeeRank::Junior, + &50000i128 + ); + + assert!(employee_id > 0); + + +} \ No newline at end of file diff --git a/submissions/week-7/day-2/Anuoluwapo/README.md b/submissions/week-7/day-2/Anuoluwapo/README.md new file mode 100644 index 000000000..012e23c44 --- /dev/null +++ b/submissions/week-7/day-2/Anuoluwapo/README.md @@ -0,0 +1,21 @@ +# Soroban Project + +## Project Structure + +This repository uses the recommended structure for a Soroban project: +```text +. +├── contracts +│   └── hello_world +│   ├── src +│   │   ├── lib.rs +│   │   └── test.rs +│   └── Cargo.toml +├── Cargo.toml +└── README.md +``` + +- New Soroban contracts can be put in `contracts`, each in their own directory. There is already a `hello_world` contract in there to get you started. +- If you initialized this project with any other example contracts via `--with-example`, those contracts will be in the `contracts` directory as well. +- Contracts should have their own `Cargo.toml` files that rely on the top-level `Cargo.toml` workspace for their dependencies. +- Frontend libraries can be added to the top-level directory as well. If you initialized this project with a frontend template via `--frontend-template` you will have those files already included. \ No newline at end of file