diff --git a/Cargo.lock b/Cargo.lock index e6cd6443e..2094098a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,7 +71,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" dependencies = [ "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -81,7 +81,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3ba0a3cf584a8ede533a1749b86040e9018cf752265fc39a71c69fe1fafaba5" dependencies = [ "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -93,7 +93,7 @@ dependencies = [ "num-bigint", "num-traits 0.2.15", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -106,7 +106,7 @@ dependencies = [ "num-traits 0.2.15", "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -173,7 +173,7 @@ checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -196,7 +196,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -307,7 +307,7 @@ dependencies = [ [[package]] name = "cairo-lang-casm" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-utils", "env_logger", @@ -316,6 +316,7 @@ dependencies = [ "num-bigint", "num-traits 0.2.15", "pretty_assertions", + "serde", "test-case", "test-log", "thiserror", @@ -323,7 +324,7 @@ dependencies = [ [[package]] name = "cairo-lang-compiler" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "anyhow", "cairo-lang-defs", @@ -347,7 +348,7 @@ dependencies = [ [[package]] name = "cairo-lang-debug" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-proc-macros", "cairo-lang-utils", @@ -358,7 +359,7 @@ dependencies = [ [[package]] name = "cairo-lang-defs" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-debug", "cairo-lang-diagnostics", @@ -379,7 +380,7 @@ dependencies = [ [[package]] name = "cairo-lang-diagnostics" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-filesystem", "cairo-lang-proc-macros", @@ -394,7 +395,7 @@ dependencies = [ [[package]] name = "cairo-lang-eq-solver" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-utils", "env_logger", @@ -408,7 +409,7 @@ dependencies = [ [[package]] name = "cairo-lang-filesystem" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-debug", "cairo-lang-utils", @@ -421,7 +422,7 @@ dependencies = [ [[package]] name = "cairo-lang-formatter" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "anyhow", "cairo-lang-diagnostics", @@ -444,8 +445,9 @@ dependencies = [ [[package]] name = "cairo-lang-language-server" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ + "anyhow", "cairo-lang-compiler", "cairo-lang-debug", "cairo-lang-defs", @@ -460,10 +462,14 @@ dependencies = [ "cairo-lang-starknet", "cairo-lang-syntax", "cairo-lang-utils", + "indoc", + "log", "lsp-types", "salsa", + "scarb-metadata", "serde", "serde_json", + "smol_str", "test-log", "tokio", "tower-lsp", @@ -471,7 +477,7 @@ dependencies = [ [[package]] name = "cairo-lang-lowering" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -486,6 +492,7 @@ dependencies = [ "cairo-lang-utils", "env_logger", "id-arena", + "indexmap", "indoc", "itertools", "log", @@ -499,7 +506,7 @@ dependencies = [ [[package]] name = "cairo-lang-parser" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", @@ -520,7 +527,7 @@ dependencies = [ [[package]] name = "cairo-lang-plugins" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -543,16 +550,16 @@ dependencies = [ [[package]] name = "cairo-lang-proc-macros" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-debug", "quote", - "syn", + "syn 1.0.103", ] [[package]] name = "cairo-lang-project" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-filesystem", "indoc", @@ -565,7 +572,7 @@ dependencies = [ [[package]] name = "cairo-lang-runner" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "anyhow", "ark-ff 0.4.0-alpha.7", @@ -593,7 +600,7 @@ dependencies = [ [[package]] name = "cairo-lang-semantic" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "assert_matches", "cairo-lang-debug", @@ -623,7 +630,7 @@ dependencies = [ [[package]] name = "cairo-lang-sierra" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "assert_matches", "bimap", @@ -651,7 +658,7 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-ap-change" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -666,7 +673,7 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-gas" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-eq-solver", "cairo-lang-sierra", @@ -683,7 +690,7 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-generator" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-debug", "cairo-lang-defs", @@ -714,8 +721,9 @@ dependencies = [ [[package]] name = "cairo-lang-sierra-to-casm" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ + "anyhow", "assert_matches", "cairo-felt", "cairo-lang-casm", @@ -738,9 +746,10 @@ dependencies = [ [[package]] name = "cairo-lang-starknet" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "anyhow", + "cairo-lang-casm", "cairo-lang-compiler", "cairo-lang-defs", "cairo-lang-diagnostics", @@ -780,7 +789,7 @@ dependencies = [ [[package]] name = "cairo-lang-syntax" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-debug", "cairo-lang-filesystem", @@ -794,7 +803,7 @@ dependencies = [ [[package]] name = "cairo-lang-syntax-codegen" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-utils", "env_logger", @@ -806,7 +815,7 @@ dependencies = [ [[package]] name = "cairo-lang-test-runner" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "anyhow", "cairo-felt", @@ -839,7 +848,7 @@ dependencies = [ [[package]] name = "cairo-lang-test-utils" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "cairo-lang-utils", "env_logger", @@ -850,13 +859,18 @@ dependencies = [ [[package]] name = "cairo-lang-utils" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "chrono", "env_logger", "indexmap", "itertools", "log", + "num-bigint", + "num-integer", + "num-traits 0.2.15", + "serde", + "serde_json", "test-case", "test-log", ] @@ -890,6 +904,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "camino" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" +dependencies = [ + "serde", +] + [[package]] name = "cc" version = "1.0.77" @@ -959,7 +982,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -972,7 +995,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -1132,7 +1155,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -1159,7 +1182,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn", + "syn 1.0.103", ] [[package]] @@ -1176,7 +1199,42 @@ checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.103", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.103", ] [[package]] @@ -1200,7 +1258,38 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", +] + +[[package]] +name = "derive_builder" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.103", +] + +[[package]] +name = "derive_builder_macro" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" +dependencies = [ + "derive_builder_core", + "syn 1.0.103", ] [[package]] @@ -1315,6 +1404,7 @@ checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" dependencies = [ "futures-channel", "futures-core", + "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -1337,6 +1427,17 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.25" @@ -1351,7 +1452,7 @@ checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -1366,6 +1467,12 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + [[package]] name = "futures-util" version = "0.3.25" @@ -1403,7 +1510,7 @@ checksum = "40803f2757f84c877f088e62420931f6e05a72514f1f03630384aa30b91d667b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -1549,6 +1656,12 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.3.0" @@ -2058,7 +2171,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -2106,7 +2219,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.103", "version_check", ] @@ -2123,18 +2236,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -2176,9 +2289,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "0.9.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" dependencies = [ "either", "rayon-core", @@ -2186,9 +2299,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -2250,6 +2363,32 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rstest" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07f2d176c472198ec1e6551dc7da28f1c089652f66a7b722676c2238ebc0edf" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version 0.4.0", +] + +[[package]] +name = "rstest_macros" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7229b505ae0706e64f37ffc54a9c163e11022a6636d58fe1f3f52018257ff9f7" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn 1.0.103", + "unicode-ident", +] + [[package]] name = "rustc-hash" version = "1.1.0" @@ -2271,7 +2410,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.16", + "semver 1.0.17", ] [[package]] @@ -2312,7 +2451,7 @@ dependencies = [ "heck 0.3.3", "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -2324,6 +2463,20 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scarb-metadata" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2480a9a896395a1414feebcfe8550b35f4dce0e6a437eeaa0c3d79ec938ddf42" +dependencies = [ + "camino", + "derive_builder", + "semver 1.0.17", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -2347,9 +2500,12 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +dependencies = [ + "serde", +] [[package]] name = "semver-parser" @@ -2362,9 +2518,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9" dependencies = [ "serde_derive", ] @@ -2380,20 +2536,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.3", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" dependencies = [ "itoa", "ryu", @@ -2408,7 +2564,7 @@ checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -2534,7 +2690,7 @@ checksum = "6569d70430f0f6edc41f6820d00acf63356e6308046ca01e57eeac22ad258c47" dependencies = [ "starknet-curve", "starknet-ff", - "syn", + "syn 1.0.103", ] [[package]] @@ -2598,6 +2754,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8234ae35e70582bfa0f1fedffa6daa248e41dd045310b19800c4a36382c8f60" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -2606,7 +2773,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", "unicode-xid", ] @@ -2649,7 +2816,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -2660,12 +2827,12 @@ checksum = "38f0c854faeb68a048f0f2dc410c5ddae3bf83854ef0e4977d58306a5edef50e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] name = "tests" -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" dependencies = [ "assert_matches", "cairo-felt", @@ -2674,6 +2841,7 @@ dependencies = [ "cairo-lang-defs", "cairo-lang-diagnostics", "cairo-lang-filesystem", + "cairo-lang-lowering", "cairo-lang-parser", "cairo-lang-plugins", "cairo-lang-runner", @@ -2690,6 +2858,7 @@ dependencies = [ "log", "num-bigint", "pretty_assertions", + "rstest", "salsa", "test-case", "test-log", @@ -2703,22 +2872,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.3", ] [[package]] @@ -2793,7 +2962,7 @@ checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -2870,7 +3039,7 @@ checksum = "7ebd99eec668d0a450c177acbc4d05e0d0d13b1f8d3db13cd706c52cbec4ac04" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -3027,7 +3196,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.103", "wasm-bindgen-shared", ] @@ -3049,7 +3218,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3186,6 +3355,6 @@ checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index 4294fd6aa..107fb5d91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ members = [ ] [workspace.package] -version = "1.0.0-alpha.3" +version = "1.0.0-alpha.6" edition = "2021" repository = "https://github.com/starkware-libs/cairo/" license = "Apache-2.0" @@ -71,8 +71,10 @@ path-clean = "0.1.0" pretty_assertions = "1.2.1" proc-macro2 = "1.0" quote = "1.0.21" -rayon = "0.9.0" +rayon = "1.7.0" +rstest = "0.16.0" salsa = "0.16.1" +scarb-metadata = "1.0.1" serde = { version = "1.0.130", features = ["derive"] } serde_json = "1.0" sha3 = "0.10.6" diff --git a/cairo b/cairo index 903337885..9c190561c 160000 --- a/cairo +++ b/cairo @@ -1 +1 @@ -Subproject commit 903337885fa19e28f59988a4952d670f72b44b34 +Subproject commit 9c190561ce1e8323665857f1a77082925c817b4c diff --git a/src/openzeppelin/lib.cairo b/src/openzeppelin/lib.cairo index 14f00389d..daffe3c5e 100644 --- a/src/openzeppelin/lib.cairo +++ b/src/openzeppelin/lib.cairo @@ -1 +1,2 @@ +mod token; mod tests; diff --git a/src/openzeppelin/tests.cairo b/src/openzeppelin/tests.cairo index ba51ab5d3..0117a1281 100644 --- a/src/openzeppelin/tests.cairo +++ b/src/openzeppelin/tests.cairo @@ -1 +1 @@ -mod test_mytest; +mod test_erc20; diff --git a/src/openzeppelin/tests/test_erc20.cairo b/src/openzeppelin/tests/test_erc20.cairo new file mode 100644 index 000000000..0b4f7f230 --- /dev/null +++ b/src/openzeppelin/tests/test_erc20.cairo @@ -0,0 +1,455 @@ +use openzeppelin::token::erc20::ERC20; +use starknet::contract_address_const; +use starknet::ContractAddress; +use starknet::testing::set_caller_address; +use integer::u256; +use integer::u256_from_felt252; + +// +// Constants +// + +const NAME: felt252 = 111; +const SYMBOL: felt252 = 222; + +fn MAX_U256() -> u256 { + u256 { + low: 0xffffffffffffffffffffffffffffffff_u128, high: 0xffffffffffffffffffffffffffffffff_u128 + } +} + +// +// Helper functions +// + +fn setup() -> (ContractAddress, u256) { + let initial_supply: u256 = u256_from_felt252(2000); + let account: ContractAddress = contract_address_const::<1>(); + // Set account as default caller + set_caller_address(account); + + ERC20::constructor(NAME, SYMBOL, initial_supply, account); + (account, initial_supply) +} + +fn set_caller_as_zero() { + set_caller_address(contract_address_const::<0>()); +} + +// +// Tests +// + +#[test] +#[available_gas(2000000)] +fn test_initializer() { + ERC20::initializer(NAME, SYMBOL); + + assert(ERC20::name() == NAME, 'Name should be NAME'); + assert(ERC20::symbol() == SYMBOL, 'Symbol should be SYMBOL'); + assert(ERC20::decimals() == 18_u8, 'Decimals should be 18'); + assert(ERC20::total_supply() == u256_from_felt252(0), 'Supply should eq 0'); +} + + +#[test] +#[available_gas(2000000)] +fn test_constructor() { + let initial_supply: u256 = u256_from_felt252(2000); + let account: ContractAddress = contract_address_const::<1>(); + let decimals: u8 = 18_u8; + + ERC20::constructor(NAME, SYMBOL, initial_supply, account); + + let owner_balance: u256 = ERC20::balance_of(account); + assert(owner_balance == initial_supply, 'Should eq inital_supply'); + + assert(ERC20::total_supply() == initial_supply, 'Should eq inital_supply'); + assert(ERC20::name() == NAME, 'Name should be NAME'); + assert(ERC20::symbol() == SYMBOL, 'Symbol should be SYMBOL'); + assert(ERC20::decimals() == decimals, 'Decimals should be 18'); +} + +#[test] +#[available_gas(2000000)] +fn test_approve() { + let (owner, supply) = setup(); + let spender: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + + let success: bool = ERC20::approve(spender, amount); + assert(success, 'Should return true'); + assert(ERC20::allowance(owner, spender) == amount, 'Spender not approved correctly'); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: approve from 0', ))] +fn test_approve_from_zero() { + let (owner, supply) = setup(); + let spender: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + + set_caller_as_zero(); + + ERC20::approve(spender, amount); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: approve to 0', ))] +fn test_approve_to_zero() { + let (owner, supply) = setup(); + let spender: ContractAddress = contract_address_const::<0>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::approve(spender, amount); +} + +#[test] +#[available_gas(2000000)] +fn test__approve() { + let (owner, supply) = setup(); + + let spender: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::_approve(owner, spender, amount); + assert(ERC20::allowance(owner, spender) == amount, 'Spender not approved correctly'); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: approve from 0', ))] +fn test__approve_from_zero() { + let owner: ContractAddress = contract_address_const::<0>(); + let spender: ContractAddress = contract_address_const::<1>(); + let amount: u256 = u256_from_felt252(100); + ERC20::_approve(owner, spender, amount); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: approve to 0', ))] +fn test__approve_to_zero() { + let (owner, supply) = setup(); + + let spender: ContractAddress = contract_address_const::<0>(); + let amount: u256 = u256_from_felt252(100); + ERC20::_approve(owner, spender, amount); +} + +#[test] +#[available_gas(2000000)] +fn test_transfer() { + let (sender, supply) = setup(); + + let recipient: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + let success: bool = ERC20::transfer(recipient, amount); + + assert(success, 'Should return true'); + assert(ERC20::balance_of(recipient) == amount, 'Balance should eq amount'); + assert(ERC20::balance_of(sender) == supply - amount, 'Should eq supply - amount'); + assert(ERC20::total_supply() == supply, 'Total supply should not change'); +} + +#[test] +#[available_gas(2000000)] +fn test__transfer() { + let (sender, supply) = setup(); + + let recipient: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + ERC20::_transfer(sender, recipient, amount); + + assert(ERC20::balance_of(recipient) == amount, 'Balance should eq amount'); + assert(ERC20::balance_of(sender) == supply - amount, 'Should eq supply - amount'); + assert(ERC20::total_supply() == supply, 'Total supply should not change'); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('u256_sub Overflow', ))] +fn test__transfer_not_enough_balance() { + let (sender, supply) = setup(); + + let recipient: ContractAddress = contract_address_const::<2>(); + let amount: u256 = supply + u256_from_felt252(1); + ERC20::_transfer(sender, recipient, amount); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: transfer from 0', ))] +fn test__transfer_from_zero() { + let sender: ContractAddress = contract_address_const::<0>(); + let recipient: ContractAddress = contract_address_const::<1>(); + let amount: u256 = u256_from_felt252(100); + ERC20::_transfer(sender, recipient, amount); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: transfer to 0', ))] +fn test__transfer_to_zero() { + let (sender, supply) = setup(); + + let recipient: ContractAddress = contract_address_const::<0>(); + let amount: u256 = u256_from_felt252(100); + ERC20::_transfer(sender, recipient, amount); +} + +#[test] +#[available_gas(2000000)] +fn test_transfer_from() { + let (owner, supply) = setup(); + + let recipient: ContractAddress = contract_address_const::<2>(); + let spender: ContractAddress = contract_address_const::<3>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::approve(spender, amount); + + set_caller_address(spender); + + let success: bool = ERC20::transfer_from(owner, recipient, amount); + assert(success, 'Should return true'); + + // Will dangle without setting as a var + let spender_allowance: u256 = ERC20::allowance(owner, spender); + + assert(ERC20::balance_of(recipient) == amount, 'Should eq amount'); + assert(ERC20::balance_of(owner) == supply - amount, 'Should eq suppy - amount'); + assert(spender_allowance == u256_from_felt252(0), 'Should eq 0'); + assert(ERC20::total_supply() == supply, 'Total supply should not change'); +} + +#[test] +#[available_gas(2000000)] +fn test_transfer_from_doesnt_consume_infinite_allowance() { + let (owner, supply) = setup(); + + let recipient: ContractAddress = contract_address_const::<2>(); + let spender: ContractAddress = contract_address_const::<3>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::approve(spender, MAX_U256()); + + set_caller_address(spender); + ERC20::transfer_from(owner, recipient, amount); + + let spender_allowance: u256 = ERC20::allowance(owner, spender); + assert(spender_allowance == MAX_U256(), 'Allowance should not change'); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('u256_sub Overflow', ))] +fn test_transfer_from_greater_than_allowance() { + let (owner, supply) = setup(); + + let recipient: ContractAddress = contract_address_const::<2>(); + let spender: ContractAddress = contract_address_const::<3>(); + let amount: u256 = u256_from_felt252(100); + let amount_plus_one: u256 = amount + u256_from_felt252(1); + + ERC20::approve(spender, amount); + + set_caller_address(spender); + + ERC20::transfer_from(owner, recipient, amount_plus_one); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: transfer to 0', ))] +fn test_transfer_from_to_zero_address() { + let (owner, supply) = setup(); + + let recipient: ContractAddress = contract_address_const::<0>(); + let spender: ContractAddress = contract_address_const::<3>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::approve(spender, amount); + + set_caller_address(spender); + + ERC20::transfer_from(owner, recipient, amount); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('u256_sub Overflow', ))] +fn test_transfer_from_from_zero_address() { + let (owner, supply) = setup(); + + let zero_address: ContractAddress = contract_address_const::<0>(); + let recipient: ContractAddress = contract_address_const::<2>(); + let spender: ContractAddress = contract_address_const::<3>(); + let amount: u256 = u256_from_felt252(100); + + set_caller_address(zero_address); + + ERC20::transfer_from(owner, recipient, amount); +} + +#[test] +#[available_gas(2000000)] +fn test_increase_allowance() { + let (owner, supply) = setup(); + + let spender: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::approve(spender, amount); + let success: bool = ERC20::increase_allowance(spender, amount); + assert(success, 'Should return true'); + + let spender_allowance: u256 = ERC20::allowance(owner, spender); + assert(spender_allowance == amount + amount, 'Should be amount * 2'); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: approve to 0', ))] +fn test_increase_allowance_to_zero_address() { + let (owner, supply) = setup(); + + let spender: ContractAddress = contract_address_const::<0>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::increase_allowance(spender, amount); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: approve from 0', ))] +fn test_increase_allowance_from_zero_address() { + let (owner, supply) = setup(); + + let zero_address: ContractAddress = contract_address_const::<0>(); + let spender: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + + set_caller_address(zero_address); + + ERC20::increase_allowance(spender, amount); +} + +#[test] +#[available_gas(2000000)] +fn test_decrease_allowance() { + let (owner, supply) = setup(); + + let spender: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::approve(spender, amount); + let success: bool = ERC20::decrease_allowance(spender, amount); + assert(success, 'Should return true'); + + let spender_allowance: u256 = ERC20::allowance(owner, spender); + assert(spender_allowance == amount - amount, 'Should be 0'); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('u256_sub Overflow', ))] +fn test_decrease_allowance_to_zero_address() { + let (owner, supply) = setup(); + + let spender: ContractAddress = contract_address_const::<0>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::decrease_allowance(spender, amount); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('u256_sub Overflow', ))] +fn test_decrease_allowance_from_zero_address() { + let (owner, supply) = setup(); + + let zero_address: ContractAddress = contract_address_const::<0>(); + let spender: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + + set_caller_address(zero_address); + + ERC20::decrease_allowance(spender, amount); +} + +#[test] +#[available_gas(2000000)] +fn test__spend_allowance_not_unlimited() { + let (owner, supply) = setup(); + + let spender: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::_approve(owner, spender, supply); + ERC20::_spend_allowance(owner, spender, amount); + assert(ERC20::allowance(owner, spender) == supply - amount, 'Should eq supply - amount'); +} + +#[test] +#[available_gas(2000000)] +fn test__spend_allowance_unlimited() { + let (owner, supply) = setup(); + + let spender: ContractAddress = contract_address_const::<2>(); + let max_minus_one: u256 = MAX_U256() - u256_from_felt252(1); + + ERC20::_approve(owner, spender, MAX_U256()); + ERC20::_spend_allowance(owner, spender, max_minus_one); + + assert(ERC20::allowance(owner, spender) == MAX_U256(), 'Allowance should not change'); +} + +#[test] +#[available_gas(2000000)] +fn test__mint() { + let minter: ContractAddress = contract_address_const::<2>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::_mint(minter, amount); + + let minter_balance: u256 = ERC20::balance_of(minter); + assert(minter_balance == amount, 'Should eq amount'); + + assert(ERC20::total_supply() == amount, 'Should eq total supply'); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: mint to 0', ))] +fn test__mint_to_zero() { + let minter: ContractAddress = contract_address_const::<0>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::_mint(minter, amount); +} + +#[test] +#[available_gas(2000000)] +fn test__burn() { + let (owner, supply) = setup(); + + let amount: u256 = u256_from_felt252(100); + ERC20::_burn(owner, amount); + + assert(ERC20::total_supply() == supply - amount, 'Should eq supply - amount'); + assert(ERC20::balance_of(owner) == supply - amount, 'Should eq supply - amount'); +} + +#[test] +#[available_gas(2000000)] +#[should_panic(expected = ('ERC20: burn from 0', ))] +fn test__burn_from_zero() { + setup(); + let zero_address: ContractAddress = contract_address_const::<0>(); + let amount: u256 = u256_from_felt252(100); + + ERC20::_burn(zero_address, amount); +} diff --git a/src/openzeppelin/tests/test_mytest.cairo b/src/openzeppelin/tests/test_mytest.cairo deleted file mode 100644 index 1f5f2ca0e..000000000 --- a/src/openzeppelin/tests/test_mytest.cairo +++ /dev/null @@ -1,5 +0,0 @@ -#[test] -#[available_gas(2000000)] -fn test_pass() { - assert(true, 'Should pass'); -} diff --git a/src/openzeppelin/token.cairo b/src/openzeppelin/token.cairo new file mode 100644 index 000000000..bfe4665e0 --- /dev/null +++ b/src/openzeppelin/token.cairo @@ -0,0 +1 @@ +mod erc20; diff --git a/src/openzeppelin/token/erc20.cairo b/src/openzeppelin/token/erc20.cairo new file mode 100644 index 000000000..ad231f2d2 --- /dev/null +++ b/src/openzeppelin/token/erc20.cairo @@ -0,0 +1,207 @@ +use starknet::ContractAddress; + +trait IERC20 { + fn name() -> felt252; + fn symbol() -> felt252; + fn decimals() -> u8; + fn total_supply() -> u256; + fn balance_of(account: ContractAddress) -> u256; + fn allowance(owner: ContractAddress, spender: ContractAddress) -> u256; + fn transfer(recipient: ContractAddress, amount: u256) -> bool; + fn transfer_from(sender: ContractAddress, recipient: ContractAddress, amount: u256) -> bool; + fn approve(spender: ContractAddress, amount: u256) -> bool; +} + +#[contract] +mod ERC20 { + use openzeppelin::token::erc20::IERC20; + use starknet::get_caller_address; + use starknet::ContractAddress; + use starknet::contract_address_const; + use starknet::ContractAddressZeroable; + use zeroable::Zeroable; + + struct Storage { + _name: felt252, + _symbol: felt252, + _total_supply: u256, + _balances: LegacyMap, + _allowances: LegacyMap<(ContractAddress, ContractAddress), u256>, + } + + #[event] + fn Transfer(from: ContractAddress, to: ContractAddress, value: u256) {} + + #[event] + fn Approval(owner: ContractAddress, spender: ContractAddress, value: u256) {} + + impl ERC20 of IERC20 { + fn name() -> felt252 { + _name::read() + } + + fn symbol() -> felt252 { + _symbol::read() + } + + fn decimals() -> u8 { + 18_u8 + } + + fn total_supply() -> u256 { + _total_supply::read() + } + + fn balance_of(account: ContractAddress) -> u256 { + _balances::read(account) + } + + fn allowance(owner: ContractAddress, spender: ContractAddress) -> u256 { + _allowances::read((owner, spender)) + } + + fn transfer(recipient: ContractAddress, amount: u256) -> bool { + let sender = get_caller_address(); + _transfer(sender, recipient, amount); + true + } + + fn transfer_from( + sender: ContractAddress, recipient: ContractAddress, amount: u256 + ) -> bool { + let caller = get_caller_address(); + _spend_allowance(sender, caller, amount); + _transfer(sender, recipient, amount); + true + } + + fn approve(spender: ContractAddress, amount: u256) -> bool { + let caller = get_caller_address(); + _approve(caller, spender, amount); + true + } + } + + #[constructor] + fn constructor( + name: felt252, symbol: felt252, initial_supply: u256, recipient: ContractAddress + ) { + initializer(name, symbol); + _mint(recipient, initial_supply); + } + + #[view] + fn name() -> felt252 { + ERC20::name() + } + + #[view] + fn symbol() -> felt252 { + ERC20::symbol() + } + + #[view] + fn decimals() -> u8 { + ERC20::decimals() + } + + #[view] + fn total_supply() -> u256 { + ERC20::total_supply() + } + + #[view] + fn balance_of(account: ContractAddress) -> u256 { + ERC20::balance_of(account) + } + + #[view] + fn allowance(owner: ContractAddress, spender: ContractAddress) -> u256 { + ERC20::allowance(owner, spender) + } + + #[external] + fn transfer(recipient: ContractAddress, amount: u256) -> bool { + ERC20::transfer(recipient, amount) + } + + #[external] + fn transfer_from(sender: ContractAddress, recipient: ContractAddress, amount: u256) -> bool { + ERC20::transfer_from(sender, recipient, amount) + } + + #[external] + fn approve(spender: ContractAddress, amount: u256) -> bool { + ERC20::approve(spender, amount) + } + + #[external] + fn increase_allowance(spender: ContractAddress, added_value: u256) -> bool { + _increase_allowance(spender, added_value) + } + + #[external] + fn decrease_allowance(spender: ContractAddress, subtracted_value: u256) -> bool { + _decrease_allowance(spender, subtracted_value) + } + + /// + /// Internals + /// + + fn initializer(name_: felt252, symbol_: felt252) { + _name::write(name_); + _symbol::write(symbol_); + } + + fn _increase_allowance(spender: ContractAddress, added_value: u256) -> bool { + let caller = get_caller_address(); + _approve(caller, spender, _allowances::read((caller, spender)) + added_value); + true + } + + fn _decrease_allowance(spender: ContractAddress, subtracted_value: u256) -> bool { + let caller = get_caller_address(); + _approve(caller, spender, _allowances::read((caller, spender)) - subtracted_value); + true + } + + fn _mint(recipient: ContractAddress, amount: u256) { + assert(!recipient.is_zero(), 'ERC20: mint to 0'); + _total_supply::write(_total_supply::read() + amount); + _balances::write(recipient, _balances::read(recipient) + amount); + Transfer(contract_address_const::<0>(), recipient, amount); + } + + fn _burn(account: ContractAddress, amount: u256) { + assert(!account.is_zero(), 'ERC20: burn from 0'); + _total_supply::write(_total_supply::read() - amount); + _balances::write(account, _balances::read(account) - amount); + Transfer(account, contract_address_const::<0>(), amount); + } + + fn _approve(owner: ContractAddress, spender: ContractAddress, amount: u256) { + assert(!owner.is_zero(), 'ERC20: approve from 0'); + assert(!spender.is_zero(), 'ERC20: approve to 0'); + _allowances::write((owner, spender), amount); + Approval(owner, spender, amount); + } + + fn _transfer(sender: ContractAddress, recipient: ContractAddress, amount: u256) { + assert(!sender.is_zero(), 'ERC20: transfer from 0'); + assert(!recipient.is_zero(), 'ERC20: transfer to 0'); + _balances::write(sender, _balances::read(sender) - amount); + _balances::write(recipient, _balances::read(recipient) + amount); + Transfer(sender, recipient, amount); + } + + fn _spend_allowance(owner: ContractAddress, spender: ContractAddress, amount: u256) { + let current_allowance = _allowances::read((owner, spender)); + let ONES_MASK = 0xffffffffffffffffffffffffffffffff_u128; + let is_unlimited_allowance = + current_allowance.low == ONES_MASK & current_allowance.high == ONES_MASK; + if !is_unlimited_allowance { + _approve(owner, spender, current_allowance - amount); + } + } +}