diff --git a/.tool-versions b/.tool-versions index dc8930c0..120e90d0 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -scarb 2.6.5 -starknet-foundry 0.25.0 +scarb 2.8.2 +starknet-foundry 0.30.0 \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb2aa6a5..49365e54 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing -When contributing to this repository, please first discuss the change you wish to make via issue or in the telegram channel before making a change. +When contributing to this repository, please first discuss the change you wish to make via issue or in the telegram channel before making a change. Join the telegram channel: https://t.me/StarknetByExample @@ -32,6 +32,7 @@ Please note we have a code of conduct, please follow it in all your interactions 1. Clone this repository. 2. Rust related packages: + - Install toolchain providing `cargo` using [rustup](https://rustup.rs/). - Install [mdBook](https://rust-lang.github.io/mdBook/guide/installation.html) and the required extension with `cargo install mdbook mdbook-i18n-helpers mdbook-last-changed `. @@ -60,8 +61,11 @@ You can add or modify examples in the `listings` directory. Each listing is a sc You can find a template of a blank scarb project in the `listings/template` directory. (You can also use `scarb init` to create a new scarb project, but be sure to remove the generated git repository) -Here's the required `Scarb.toml` configuration: - +You can choose to use standard cairo with `cairo-test` or Starknet Foundry with `snforge_std`. +Please use the appropriate `Scarb.toml` configuration. `scarb test` will automatically resolve to `snforge test` if `snforge_std` is in the dependencies. + +Here's the required `Scarb.toml` configuration for **Cairo test**: + ```toml [package] name = "pkg_name" @@ -73,14 +77,45 @@ version.workspace = true [dependencies] starknet.workspace = true # Uncomment the following lines if you want to use additional dependencies: -# Starknet Foundry: -# snforge_std.workspace = true # OpenZeppelin: # openzeppelin.workspace = true # If you want to use another Starknet By Example's listing, you can add it as a dependency like this: # erc20 = { path = "../../getting-started/erc20" } +[dev-dependencies] +cairo_test.workspace = true + +[scripts] +test.workspace = true + +[[target.starknet-contract]] +casm = true +``` + +Here's the required `Scarb.toml` configuration for **Starknet Foundry**: + +```toml +[package] +name = "pkg_name" +version.workspace = true + +# Specify that this can be used as a dependency in another scarb project: +[lib] + +[dependencies] +starknet.workspace = true +snforge_std.workspace = true +# Uncomment the following lines if you want to use additional dependencies: +# OpenZeppelin: +# openzeppelin.workspace = true + +# If you want to use another Starknet By Example's listing, you can add it as a dependency like this: +# erc20 = { path = "../../getting-started/erc20" } + +[dev-dependencies] +assert_macros.workspace = true + [scripts] test.workspace = true @@ -89,6 +124,7 @@ casm = true ``` You also NEED to do the following: + - Remove the generated git repository, `rm -rf .git` (this is important!) - Double check that the `pkg_name` is the same as the name of the directory @@ -110,28 +146,40 @@ You can also use `scarb fmt` to format all the Cairo programs. Every listing needs to have atleast integration tests: -- Integration tests are tests that deploy the contract and interact with the provided interface(s). They should be placed on a separate file/module named `tests.cairo`. At minimal make one test to deploy the contract. +- Integration tests are tests that deploy the contract and interact with the provided interface(s). At minimal make one test to deploy the contract. -- (Optional) Unit tests do not have to deploy the contract and use the interface(s). Unit tests can use mocked implementation or state to test only one specific feature. They should be placed on the same file as the example (and hidden in the book using ANCHOR). +- (Optional) Unit tests do not have to deploy the contract and use the interface(s). Unit tests can use mocked implementation or state to test only one specific feature. -The tests modules need to have the `#[cfg(test)]` flag. +Add your contract in a specific file, you can name it `contract.cairo` or anything else. You can also add other files if needed. -Add your contract in a different file, you can name it `contract.cairo` or anything else. You can also add other files if needed. +You should add the tests in the same file as the contract, using the `#[cfg(test)]` flag and a `tests` module. With the usage of ANCHOR, the tests will not be displayed in the book but can be optionally be displayed by using the `{{#rustdoc_include ...}}` syntax. Here's a sample `lib.cairo` file: ```cairo mod contract; +// any other modules you want +``` + +And in the `contract.cairo` file: + +```cairo +// ANCHOR: contract +// Write your contract here +// ANCHOR_END: contract #[cfg(test)] -mod tests; +mod tests { + // Write your tests for the contract here +} ``` -You can also use Starknet Foundry to write and run your tests. +You can use Starknet Foundry to write and run your tests. ### Use of anchor You can add delimiting comments to select part of the code in the book. + ```cairo file.cairo: @@ -144,11 +192,12 @@ c Then, in the markdown file, you can use the following syntax to include only the code between the delimiting comments: -```markdown - ```rust - {{#include ../../listings/path/to/listing/src/contract.cairo:anchor_name}} - \``` -``` +````markdown +````rust +{{#include ../../listings/path/to/listing/src/contract.cairo:anchor_name}} +\``` +```` +```` This will result in the following code being included in the book: @@ -156,8 +205,19 @@ This will result in the following code being included in the book: b ``` +Using `#rustdoc_include` you can have the same result, but users can expand the code in the book to see the whole file (used for showing tests): + +````markdown +````rust +{{#rustdoc_include ../../listings/path/to/listing/src/contract.cairo:anchor_name}} +\``` +```` +```` + ## Translations +> Translations efforts are currently on hold. If you are interested in helping out, please send a message in the telegram channel. + To work with translations, those are the steps to update the translated content: - Run a local server for the language you want to edit: `./translations.sh zh-cn` for instance. If no language is provided, the script will only extract translations from english. @@ -195,21 +255,21 @@ orientation. Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or -advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a +- Other conduct which could reasonably be considered inappropriate in a professional setting ### Our Responsibilities @@ -253,3 +313,5 @@ available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ + +Copyright (c) 2024 Nethermind diff --git a/LICENSE b/LICENSE index 006546af..1a461a21 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Nethermind +Copyright (c) 2024 Nethermind Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Scarb.lock b/Scarb.lock index c84915d1..ee2add0e 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -5,17 +5,11 @@ version = 1 name = "advanced_factory" version = "0.1.0" dependencies = [ - "alexandria_storage", "components", "crowdfunding", "snforge_std", ] -[[package]] -name = "alexandria_storage" -version = "0.3.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=800f5ad#800f5ad217847b5ded63c0302a444161766ee9d6" - [[package]] name = "bytearray" version = "0.1.0" @@ -117,12 +111,100 @@ dependencies = [ [[package]] name = "openzeppelin" -version = "0.14.0" -source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.14.0#f091c4f51ddeb10297db984acae965328c5a4e5b" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:5dc87a71f0f5d045e02e5bc5ea7a9b0360bbbc3f388b846006280d266feac192" +dependencies = [ + "openzeppelin_merkle_tree", + "openzeppelin_presets", + "openzeppelin_security", + "openzeppelin_token", + "openzeppelin_upgrades", +] [[package]] -name = "scarb" -version = "0.1.0" +name = "openzeppelin_access" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:b9139449e53d715992b2d9e887c0c723d886419bee7ceb5561648c70bd6d3174" +dependencies = [ + "openzeppelin_introspection", + "openzeppelin_utils", +] + +[[package]] +name = "openzeppelin_account" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:841bb881adbe98b64fee1dc1329f6e3fbabdfbd9fa65c66ffb54c55f13764bce" +dependencies = [ + "openzeppelin_introspection", + "openzeppelin_utils", +] + +[[package]] +name = "openzeppelin_governance" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:a9d9c983cfd4369e7bbb69433fb264edf376805ed873b1f70a287825a6bd1eaf" +dependencies = [ + "openzeppelin_access", + "openzeppelin_introspection", +] + +[[package]] +name = "openzeppelin_introspection" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:312bc2e531f036480ad7392dbb31042c38d875ef9dbb5578ea8de5c05e35b7d8" + +[[package]] +name = "openzeppelin_merkle_tree" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:8e264c8d5f0591262a235a445b8ca78dd5580c251707b218b829b6b4d6f84a34" + +[[package]] +name = "openzeppelin_presets" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:7bc9db7563e434535ebd06c7598ba0f8494e791c5f80401389b356a3ebd65a08" +dependencies = [ + "openzeppelin_access", + "openzeppelin_account", + "openzeppelin_introspection", + "openzeppelin_token", + "openzeppelin_upgrades", +] + +[[package]] +name = "openzeppelin_security" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:b7497f5e55c6d9f1d7606ad0d12719e3c04765e266fb91fb72740e0af41d03f3" + +[[package]] +name = "openzeppelin_token" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:7074c23fbc300b3cccff1037264dfdbe976fb11ae42ce687f4a8ce469adc552a" +dependencies = [ + "openzeppelin_account", + "openzeppelin_governance", + "openzeppelin_introspection", +] + +[[package]] +name = "openzeppelin_upgrades" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:4de95a7fb8955e63711f34bb954676f6cef127b44b570c0535d7781297821b44" + +[[package]] +name = "openzeppelin_utils" +version = "0.16.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:a494aeb5f1371db7f22e922196aa41d1d1698877a766a838350c0b6ffe49fda2" [[package]] name = "simple_account" @@ -142,10 +224,20 @@ dependencies = [ "erc20", ] +[[package]] +name = "snforge_scarb_plugin" +version = "0.2.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:2e4ce3ebe3f49548bd26908391b5d78537a765d827df0d96c32aeb88941d0d67" + [[package]] name = "snforge_std" -version = "0.25.0" -source = "git+https://github.com/foundry-rs/starknet-foundry.git?tag=v0.25.0#5b366e24821e530fea97f11b211d220e8493fbea" +version = "0.30.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:2f3c4846881813ac0f5d1460981249c9f5e2a6831e752beedf9b70975495b4ec" +dependencies = [ + "snforge_scarb_plugin", +] [[package]] name = "staking" @@ -162,10 +254,6 @@ version = "0.1.0" name = "store_using_packing" version = "0.1.0" -[[package]] -name = "storing_arrays" -version = "0.1.0" - [[package]] name = "storing_custom_types" version = "0.1.0" @@ -191,13 +279,6 @@ dependencies = [ name = "upgradeable_contract" version = "0.1.0" -[[package]] -name = "using_lists" -version = "0.1.0" -dependencies = [ - "alexandria_storage", -] - [[package]] name = "variables" version = "0.1.0" diff --git a/Scarb.toml b/Scarb.toml index 8df8fcb2..f8dd7cba 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -12,12 +12,12 @@ test = "$(git rev-parse --show-toplevel)/scripts/test_resolver.sh" [workspace.tool.snforge] [workspace.dependencies] -starknet = ">=2.6.4" -openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag="v0.14.0" } +starknet = "2.8.2" +cairo_test = "2.8.2" +assert_macros = "2.8.2" +snforge_std = "0.30.0" +openzeppelin = "0.16.0" components = { path = "listings/applications/components" } -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.25.0" } -# The latest Alexandria release supports only Cairo v2.6.0, so using explicit rev that supports Cairo v2.6.3 -alexandria_storage = { git = "https://github.com/keep-starknet-strange/alexandria.git", rev="800f5ad" } [workspace.package] description = "Collection of examples of how to use the Cairo programming language to create smart contracts on Starknet." @@ -27,8 +27,5 @@ license = "MIT" authors = ["julio4", "msaug"] version = "0.1.0" -[scripts] -test.workspace = true - [tool] snforge.workspace = true diff --git a/listings/advanced-concepts/ecdsa_verification/Scarb.toml b/listings/advanced-concepts/ecdsa_verification/Scarb.toml index 9c069f75..96ed1b58 100644 --- a/listings/advanced-concepts/ecdsa_verification/Scarb.toml +++ b/listings/advanced-concepts/ecdsa_verification/Scarb.toml @@ -1,12 +1,14 @@ [package] name = "ecdsa_verification" version.workspace = true -edition = '2023_11' - +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/advanced-concepts/ecdsa_verification/src/ecdsa_verification.cairo b/listings/advanced-concepts/ecdsa_verification/src/ecdsa_verification.cairo index 8fd21af0..4fbbb6ff 100644 --- a/listings/advanced-concepts/ecdsa_verification/src/ecdsa_verification.cairo +++ b/listings/advanced-concepts/ecdsa_verification/src/ecdsa_verification.cairo @@ -22,14 +22,8 @@ trait IVerifySignature { mod verifySignature { use super::IVerifySignature; use core::starknet::eth_address::EthAddress; - use starknet::get_caller_address; - use starknet::secp256_trait; - use starknet::secp256k1::{Secp256k1Point}; - use starknet::{SyscallResult, SyscallResultTrait}; - use starknet::secp256_trait::{ - Secp256Trait, Secp256PointTrait, Signature, signature_from_vrs, recover_public_key, - is_signature_entry_valid - }; + use starknet::secp256k1::Secp256k1Point; + use starknet::secp256_trait::{Signature, signature_from_vrs, recover_public_key,}; use starknet::eth_signature::{verify_eth_signature, public_key_point_to_eth_address}; #[storage] @@ -74,7 +68,8 @@ mod verifySignature { verify_eth_signature(:msg_hash, :signature, :eth_address); } - /// Recovers the public key from an Ethereum signature and verifies that it matches the given Ethereum address. + /// Recovers the public key from an Ethereum signature and verifies that it matches the + /// given Ethereum address. /// /// # Arguments /// @@ -98,10 +93,7 @@ mod verifySignature { #[cfg(test)] mod tests { - use starknet::secp256_trait::{ - Secp256Trait, Secp256PointTrait, Signature, signature_from_vrs, recover_public_key, - is_signature_entry_valid - }; + use starknet::secp256_trait::{Signature, signature_from_vrs, recover_public_key,}; use starknet::EthAddress; use starknet::secp256k1::{Secp256k1Point}; use starknet::eth_signature::{verify_eth_signature, public_key_point_to_eth_address}; @@ -121,14 +113,14 @@ mod tests { #[test] fn test_verify_eth_signature() { let (msg_hash, signature, eth_address) = get_message_and_signature(); - verify_eth_signature(:msg_hash, :signature, :eth_address); + verify_eth_signature(msg_hash, signature, eth_address); } #[test] fn test_secp256k1_recover_public_key() { let (msg_hash, signature, eth_address) = get_message_and_signature(); let public_key_point = recover_public_key::(msg_hash, signature).unwrap(); - let calculated_eth_address = public_key_point_to_eth_address(:public_key_point); + let calculated_eth_address = public_key_point_to_eth_address(public_key_point); assert_eq!(calculated_eth_address, eth_address); } } diff --git a/listings/advanced-concepts/hash_solidity_compatible/Scarb.toml b/listings/advanced-concepts/hash_solidity_compatible/Scarb.toml index 702fea43..9f3c6244 100644 --- a/listings/advanced-concepts/hash_solidity_compatible/Scarb.toml +++ b/listings/advanced-concepts/hash_solidity_compatible/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "hash_solidity_compatible" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/advanced-concepts/hash_solidity_compatible/src/contract.cairo b/listings/advanced-concepts/hash_solidity_compatible/src/contract.cairo index 08e357f5..d46b5dcc 100644 --- a/listings/advanced-concepts/hash_solidity_compatible/src/contract.cairo +++ b/listings/advanced-concepts/hash_solidity_compatible/src/contract.cairo @@ -5,7 +5,7 @@ pub trait ISolidityHashExample { #[starknet::contract] pub mod SolidityHashExample { - use keccak::{keccak_u256s_be_inputs}; + use core::keccak::keccak_u256s_be_inputs; use core::integer; #[storage] diff --git a/listings/advanced-concepts/hash_solidity_compatible/src/tests.cairo b/listings/advanced-concepts/hash_solidity_compatible/src/tests.cairo index cae933bc..1f344672 100644 --- a/listings/advanced-concepts/hash_solidity_compatible/src/tests.cairo +++ b/listings/advanced-concepts/hash_solidity_compatible/src/tests.cairo @@ -1,10 +1,6 @@ mod tests { - use hash_solidity_compatible::{contract::{SolidityHashExample, ISolidityHashExample}}; - use starknet::{ - ContractAddress, get_contract_address, contract_address_const, - testing::{set_contract_address} - }; - // use starknet::syscalls::call_contract_syscall; + use hash_solidity_compatible::contract::{SolidityHashExample, ISolidityHashExample}; + use starknet::{contract_address_const, testing::set_contract_address}; fn setup() -> SolidityHashExample::ContractState { let mut state = SolidityHashExample::contract_state_for_testing(); @@ -14,7 +10,6 @@ mod tests { } #[test] - #[available_gas(2000000000)] fn get_same_hash_solidity() { let mut state = setup(); let mut array: Array = array![]; @@ -24,6 +19,6 @@ mod tests { 0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6; let hash_received: u256 = state.hash_data(array.span()); - assert(hash_received == hash_expected, 'hash_received != hash_expected'); + assert_eq!(hash_received, hash_expected); } } diff --git a/listings/advanced-concepts/hash_trait/Scarb.toml b/listings/advanced-concepts/hash_trait/Scarb.toml index e810652f..44a44d27 100644 --- a/listings/advanced-concepts/hash_trait/Scarb.toml +++ b/listings/advanced-concepts/hash_trait/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "hash_trait" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/advanced-concepts/hash_trait/src/hash_trait.cairo b/listings/advanced-concepts/hash_trait/src/hash_trait.cairo index f09592f9..4dfb9994 100644 --- a/listings/advanced-concepts/hash_trait/src/hash_trait.cairo +++ b/listings/advanced-concepts/hash_trait/src/hash_trait.cairo @@ -11,6 +11,7 @@ pub trait IHashTrait { // ANCHOR: hash #[starknet::contract] pub mod HashTraits { + use starknet::storage::StoragePointerWriteAccess; use core::hash::{HashStateTrait, HashStateExTrait}; use core::{pedersen::PedersenTrait, poseidon::PoseidonTrait}; @@ -65,9 +66,6 @@ pub mod HashTraits { mod tests { use starknet::SyscallResultTrait; use super::{HashTraits, IHashTraitDispatcher, IHashTraitDispatcherTrait}; - - use core::hash::{HashStateTrait, HashStateExTrait}; - use core::{pedersen::PedersenTrait, poseidon::PoseidonTrait}; use starknet::syscalls::deploy_syscall; fn deploy() -> IHashTraitDispatcher { @@ -81,7 +79,6 @@ mod tests { #[test] - #[available_gas(20000000)] fn test_pedersen_hash() { let mut contract = deploy(); @@ -90,14 +87,10 @@ mod tests { let password = 'password.stark'; let test_hash = contract.save_user_with_pedersen(id, username, password); - assert( - test_hash == 0x6da4b4d0489989f5483d179643dafb3405b0e3b883a6c8efe5beb824ba9055a, - 'Incorrect hash output' - ); + assert_eq!(test_hash, 0x6da4b4d0489989f5483d179643dafb3405b0e3b883a6c8efe5beb824ba9055a); } #[test] - #[available_gas(20000000)] fn test_poseidon_hash() { let mut contract = deploy(); @@ -107,9 +100,6 @@ mod tests { let test_hash = contract.save_user_with_poseidon(id, username, password); - assert( - test_hash == 0x4d165e1d398ae4864854518d3c58c3d7a21ed9c1f8f3618fbb0031d208aab7b, - 'Incorrect hash output' - ); + assert_eq!(test_hash, 0x4d165e1d398ae4864854518d3c58c3d7a21ed9c1f8f3618fbb0031d208aab7b); } } diff --git a/listings/advanced-concepts/library_calls/Scarb.toml b/listings/advanced-concepts/library_calls/Scarb.toml index 0ea12255..e077de16 100644 --- a/listings/advanced-concepts/library_calls/Scarb.toml +++ b/listings/advanced-concepts/library_calls/Scarb.toml @@ -1,14 +1,15 @@ [package] name = "library_calls" version.workspace = true -edition = "2023_11" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true -[[target.starknet-contract]] \ No newline at end of file +[[target.starknet-contract]] diff --git a/listings/advanced-concepts/library_calls/src/library_call.cairo b/listings/advanced-concepts/library_calls/src/library_call.cairo index a9f7cd56..93b7b6db 100644 --- a/listings/advanced-concepts/library_calls/src/library_call.cairo +++ b/listings/advanced-concepts/library_calls/src/library_call.cairo @@ -25,8 +25,8 @@ pub mod MathUtils { // contract B to make library call to the class of contract A #[starknet::contract] pub mod MathUtilsLibraryCall { - use starknet::{class_hash::class_hash_const, ContractAddress}; use super::{IMathUtilsDispatcherTrait, IMathUtilsLibraryDispatcher}; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; #[storage] struct Storage { diff --git a/listings/advanced-concepts/library_calls/src/tests.cairo b/listings/advanced-concepts/library_calls/src/tests.cairo index 1b9ecdf0..6458ef4d 100644 --- a/listings/advanced-concepts/library_calls/src/tests.cairo +++ b/listings/advanced-concepts/library_calls/src/tests.cairo @@ -1,12 +1,11 @@ mod tests { - use starknet::syscalls::{deploy_syscall}; + use starknet::syscalls::deploy_syscall; use starknet::SyscallResultTrait; use library_calls::library_call::{ MathUtils, MathUtilsLibraryCall, IMathUtilsDispatcher, IMathUtilsDispatcherTrait }; #[test] - #[available_gas(20000000)] fn test_library_dispatcher() { let math_utils_class_hash: starknet::ClassHash = MathUtils::TEST_CLASS_HASH .try_into() diff --git a/listings/advanced-concepts/simple_account/Scarb.toml b/listings/advanced-concepts/simple_account/Scarb.toml index f6fbac41..7454c359 100644 --- a/listings/advanced-concepts/simple_account/Scarb.toml +++ b/listings/advanced-concepts/simple_account/Scarb.toml @@ -1,8 +1,7 @@ [package] name = "simple_account" version.workspace = true -edition = '2023_11' - +edition = "2024_07" [dependencies] starknet.workspace = true diff --git a/listings/advanced-concepts/simple_account/src/simple_account.cairo b/listings/advanced-concepts/simple_account/src/simple_account.cairo index 6de8b4ae..6de72c81 100644 --- a/listings/advanced-concepts/simple_account/src/simple_account.cairo +++ b/listings/advanced-concepts/simple_account/src/simple_account.cairo @@ -15,6 +15,7 @@ mod simpleAccount { use starknet::account::Call; use core::num::traits::Zero; use core::ecdsa::check_ecdsa_signature; + use starknet::storage::{StoragePointerWriteAccess, StoragePointerReadAccess}; // Implement SRC5 with openzeppelin use openzeppelin::account::interface; diff --git a/listings/advanced-concepts/store_using_packing/Scarb.toml b/listings/advanced-concepts/store_using_packing/Scarb.toml index 4854defc..2625aca3 100644 --- a/listings/advanced-concepts/store_using_packing/Scarb.toml +++ b/listings/advanced-concepts/store_using_packing/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "store_using_packing" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/advanced-concepts/store_using_packing/src/contract.cairo b/listings/advanced-concepts/store_using_packing/src/contract.cairo index 5f124ac2..8ef6b2db 100644 --- a/listings/advanced-concepts/store_using_packing/src/contract.cairo +++ b/listings/advanced-concepts/store_using_packing/src/contract.cairo @@ -12,6 +12,7 @@ pub trait ITime { #[starknet::contract] pub mod TimeContract { + use starknet::storage::{StoragePointerWriteAccess, StoragePointerReadAccess}; use super::Time; use starknet::storage_access::StorePacking; diff --git a/listings/advanced-concepts/store_using_packing/src/tests.cairo b/listings/advanced-concepts/store_using_packing/src/tests.cairo index 64a99b4e..eb888025 100644 --- a/listings/advanced-concepts/store_using_packing/src/tests.cairo +++ b/listings/advanced-concepts/store_using_packing/src/tests.cairo @@ -5,7 +5,6 @@ mod tests { use starknet::syscalls::deploy_syscall; #[test] - #[available_gas(20000000)] fn test_packing() { // Set up. let mut calldata: Array = array![]; @@ -21,7 +20,7 @@ mod tests { // Read the stored struct. let read_time: Time = contract.get(); - assert(read_time.hour == time.hour, 'Time.hour mismatch'); - assert(read_time.minute == time.minute, 'Time.minute mismatch'); + assert_eq!(read_time.hour, time.hour); + assert_eq!(read_time.minute, time.minute); } } diff --git a/listings/advanced-concepts/storing_arrays/.gitignore b/listings/advanced-concepts/storing_arrays/.gitignore deleted file mode 100644 index eb5a316c..00000000 --- a/listings/advanced-concepts/storing_arrays/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target diff --git a/listings/advanced-concepts/storing_arrays/Scarb.lock b/listings/advanced-concepts/storing_arrays/Scarb.lock deleted file mode 100644 index 092d80f9..00000000 --- a/listings/advanced-concepts/storing_arrays/Scarb.lock +++ /dev/null @@ -1,6 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "storing_arrays" -version.workspace = true diff --git a/listings/advanced-concepts/storing_arrays/Scarb.toml b/listings/advanced-concepts/storing_arrays/Scarb.toml deleted file mode 100644 index 53ab4279..00000000 --- a/listings/advanced-concepts/storing_arrays/Scarb.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "storing_arrays" -version.workspace = true -edition = '2023_11' - -[dependencies] -starknet.workspace = true - -[scripts] -test.workspace = true - -[[target.starknet-contract]] diff --git a/listings/advanced-concepts/storing_arrays/src/contract.cairo b/listings/advanced-concepts/storing_arrays/src/contract.cairo deleted file mode 100644 index 991631be..00000000 --- a/listings/advanced-concepts/storing_arrays/src/contract.cairo +++ /dev/null @@ -1,96 +0,0 @@ -use starknet::SyscallResultTrait; -use starknet::{Store, SyscallResult}; -use starknet::storage_access::StorageBaseAddress; - -// ANCHOR: StorageAccessImpl -impl StoreFelt252Array of Store> { - fn read(address_domain: u32, base: StorageBaseAddress) -> SyscallResult> { - StoreFelt252Array::read_at_offset(address_domain, base, 0) - } - - fn write( - address_domain: u32, base: StorageBaseAddress, value: Array - ) -> SyscallResult<()> { - StoreFelt252Array::write_at_offset(address_domain, base, 0, value) - } - - fn read_at_offset( - address_domain: u32, base: StorageBaseAddress, mut offset: u8 - ) -> SyscallResult> { - let mut arr: Array = array![]; - - // Read the stored array's length. If the length is greater than 255, the read will fail. - let len: u8 = Store::::read_at_offset(address_domain, base, offset) - .expect('Storage Span too large'); - offset += 1; - - // Sequentially read all stored elements and append them to the array. - let exit = len + offset; - loop { - if offset >= exit { - break; - } - - let value = Store::::read_at_offset(address_domain, base, offset).unwrap(); - arr.append(value); - offset += Store::::size(); - }; - - // Return the array. - Result::Ok(arr) - } - - fn write_at_offset( - address_domain: u32, base: StorageBaseAddress, mut offset: u8, mut value: Array - ) -> SyscallResult<()> { - // Store the length of the array in the first storage slot. - let len: u8 = value.len().try_into().expect('Storage - Span too large'); - Store::::write_at_offset(address_domain, base, offset, len).unwrap(); - offset += 1; - - // Store the array elements sequentially - while let Option::Some(element) = value - .pop_front() { - Store::::write_at_offset(address_domain, base, offset, element).unwrap(); - offset += Store::::size(); - }; - - Result::Ok(()) - } - - fn size() -> u8 { - 255 * Store::::size() - } -} -// ANCHOR_END: StorageAccessImpl - -// ANCHOR: StoreArrayContract -#[starknet::interface] -pub trait IStoreArrayContract { - fn store_array(ref self: TContractState, arr: Array); - fn read_array(self: @TContractState) -> Array; -} - -#[starknet::contract] -pub mod StoreArrayContract { - use super::StoreFelt252Array; - - #[storage] - struct Storage { - arr: Array - } - - #[abi(embed_v0)] - impl StoreArrayImpl of super::IStoreArrayContract { - fn store_array(ref self: ContractState, arr: Array) { - self.arr.write(arr); - } - - fn read_array(self: @ContractState) -> Array { - self.arr.read() - } - } -} -// ANCHOR_END: StoreArrayContract - - diff --git a/listings/advanced-concepts/storing_arrays/src/lib.cairo b/listings/advanced-concepts/storing_arrays/src/lib.cairo deleted file mode 100644 index 11ada17a..00000000 --- a/listings/advanced-concepts/storing_arrays/src/lib.cairo +++ /dev/null @@ -1,4 +0,0 @@ -mod contract; - -#[cfg(test)] -mod tests; diff --git a/listings/advanced-concepts/storing_arrays/src/tests.cairo b/listings/advanced-concepts/storing_arrays/src/tests.cairo deleted file mode 100644 index 7c4093a5..00000000 --- a/listings/advanced-concepts/storing_arrays/src/tests.cairo +++ /dev/null @@ -1,62 +0,0 @@ -mod tests { - use starknet::SyscallResultTrait; - use storing_arrays::contract::{ - StoreArrayContract, IStoreArrayContractDispatcher, IStoreArrayContractDispatcherTrait - }; - use starknet::syscalls::deploy_syscall; - - #[test] - #[available_gas(20000000)] - fn test_array_storage() { - // Set up. - let mut calldata: Array = array![]; - let (address0, _) = deploy_syscall( - StoreArrayContract::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ) - .unwrap_syscall(); - let mut contract = IStoreArrayContractDispatcher { contract_address: address0 }; - - // Store an array. - let mut array: Array = array![]; - array.append(1); - array.append(2); - contract.store_array(array); - - // Read the array. - let read_array = contract.read_array(); - assert(read_array.len() == 2, 'Array length mismatch'); - assert(*read_array[0] == 1, 'Array element mismatch'); - assert(*read_array[1] == 2, 'Array element mismatch'); - } - - #[test] - #[available_gas(20000000000)] - #[should_panic(expected: ('Storage - Span too large', 'ENTRYPOINT_FAILED'))] - fn test_array_storage_too_large() { - // Set up. - let mut calldata: Array = array![]; - let (address0, _) = deploy_syscall( - StoreArrayContract::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false - ) - .unwrap(); - let mut contract = IStoreArrayContractDispatcher { contract_address: address0 }; - - // Store an array. - let mut array: Array = array![]; - let mut i = 0; - loop { - if i == 256 { - break (); - } - array.append(i); - i += 1; - }; - contract.store_array(array); - - // Read the array. - let read_array = contract.read_array(); - assert(read_array.len() == 2, 'Array too large'); - assert(*read_array[0] == 1, 'Array element mismatch'); - assert(*read_array[1] == 2, 'Array element mismatch'); - } -} diff --git a/listings/advanced-concepts/struct_as_mapping_key/Scarb.toml b/listings/advanced-concepts/struct_as_mapping_key/Scarb.toml index 84d888e3..8bfd3839 100644 --- a/listings/advanced-concepts/struct_as_mapping_key/Scarb.toml +++ b/listings/advanced-concepts/struct_as_mapping_key/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "struct_as_mapping_key" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo b/listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo index e3733d43..2708e396 100644 --- a/listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo +++ b/listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo @@ -13,12 +13,12 @@ pub trait IPetRegistry { #[starknet::contract] pub mod PetRegistry { - use core::hash::{HashStateTrait, Hash}; use super::Pet; + use starknet::storage::{Map, StorageMapReadAccess, StorageMapWriteAccess}; #[storage] struct Storage { - registration_time: LegacyMap::, + registration_time: Map::, } #[abi(embed_v0)] diff --git a/listings/advanced-concepts/struct_as_mapping_key/src/test.cairo b/listings/advanced-concepts/struct_as_mapping_key/src/test.cairo index b78463ab..34ebdf26 100644 --- a/listings/advanced-concepts/struct_as_mapping_key/src/test.cairo +++ b/listings/advanced-concepts/struct_as_mapping_key/src/test.cairo @@ -10,7 +10,6 @@ mod tests { } #[test] - #[available_gas(20000000)] fn test_e2e() { // Set up. let mut calldata: Array = array![]; @@ -27,6 +26,6 @@ mod tests { // Read the array. let registration_date = contract.get_registration_date(pet); - assert(registration_date == 1234, 'registration_date'); + assert_eq!(registration_date, 1234); } } diff --git a/listings/advanced-concepts/using_lists/.gitignore b/listings/advanced-concepts/using_lists/.gitignore deleted file mode 100644 index eb5a316c..00000000 --- a/listings/advanced-concepts/using_lists/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target diff --git a/listings/advanced-concepts/using_lists/Scarb.lock b/listings/advanced-concepts/using_lists/Scarb.lock deleted file mode 100644 index 924a0297..00000000 --- a/listings/advanced-concepts/using_lists/Scarb.lock +++ /dev/null @@ -1,14 +0,0 @@ -# Code generated by scarb DO NOT EDIT. -version = 1 - -[[package]] -name = "alexandria_storage" -version = "0.2.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git?rev=ae1d514#ae1d5149ff601a7ac5b39edc867d33ebd83d7f4f" - -[[package]] -name = "using_lists" -version.workspace = true -dependencies = [ - "alexandria_storage", -] diff --git a/listings/advanced-concepts/using_lists/Scarb.toml b/listings/advanced-concepts/using_lists/Scarb.toml deleted file mode 100644 index 20fc9020..00000000 --- a/listings/advanced-concepts/using_lists/Scarb.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "using_lists" -version.workspace = true -edition = '2023_11' - -[dependencies] -starknet.workspace = true -alexandria_storage.workspace = true - -[scripts] -test.workspace = true - -[[target.starknet-contract]] diff --git a/listings/advanced-concepts/using_lists/src/contract.cairo b/listings/advanced-concepts/using_lists/src/contract.cairo deleted file mode 100644 index 9ee274db..00000000 --- a/listings/advanced-concepts/using_lists/src/contract.cairo +++ /dev/null @@ -1,72 +0,0 @@ -#[derive(Copy, Drop, Serde, starknet::Store)] -pub struct Task { - pub description: felt252, - pub status: felt252 -} - -#[starknet::interface] -pub trait IListExample { - fn add_in_amount(ref self: TContractState, number: u128); - fn add_in_task(ref self: TContractState, description: felt252, status: felt252); - fn is_empty_list(self: @TContractState) -> bool; - fn list_length(self: @TContractState) -> u32; - fn get_from_index(self: @TContractState, index: u32) -> u128; - fn set_from_index(ref self: TContractState, index: u32, number: u128); - fn pop_front_list(ref self: TContractState); - fn array_conversion(self: @TContractState) -> Array; -} - -#[starknet::contract] -pub mod ListExample { - use super::Task; - use alexandria_storage::list::{List, ListTrait}; - - #[storage] - pub struct Storage { - amounts: List, - tasks: List - } - - #[abi(embed_v0)] - impl ListExample of super::IListExample { - fn add_in_amount(ref self: ContractState, number: u128) { - let mut current_amount_list = self.amounts.read(); - current_amount_list.append(number).unwrap(); - } - - fn add_in_task(ref self: ContractState, description: felt252, status: felt252) { - let new_task = Task { description: description, status: status }; - let mut current_tasks_list = self.tasks.read(); - current_tasks_list.append(new_task).unwrap(); - } - - fn is_empty_list(self: @ContractState) -> bool { - let mut current_amount_list = self.amounts.read(); - current_amount_list.is_empty() - } - - fn list_length(self: @ContractState) -> u32 { - let mut current_amount_list = self.amounts.read(); - current_amount_list.len() - } - - fn get_from_index(self: @ContractState, index: u32) -> u128 { - self.amounts.read()[index] - } - - fn set_from_index(ref self: ContractState, index: u32, number: u128) { - let mut current_amount_list = self.amounts.read(); - current_amount_list.set(index, number).unwrap(); - } - - fn pop_front_list(ref self: ContractState) { - let mut current_amount_list = self.amounts.read(); - current_amount_list.pop_front().unwrap().unwrap(); - } - - fn array_conversion(self: @ContractState) -> Array { - let mut current_amount_list = self.amounts.read(); - current_amount_list.array().unwrap() - } - } -} diff --git a/listings/advanced-concepts/using_lists/src/lib.cairo b/listings/advanced-concepts/using_lists/src/lib.cairo deleted file mode 100644 index 11ada17a..00000000 --- a/listings/advanced-concepts/using_lists/src/lib.cairo +++ /dev/null @@ -1,4 +0,0 @@ -mod contract; - -#[cfg(test)] -mod tests; diff --git a/listings/advanced-concepts/using_lists/src/tests.cairo b/listings/advanced-concepts/using_lists/src/tests.cairo deleted file mode 100644 index 98f667c3..00000000 --- a/listings/advanced-concepts/using_lists/src/tests.cairo +++ /dev/null @@ -1,101 +0,0 @@ -use using_lists::contract::IListExample; -use using_lists::contract::{Task, ListExample}; -use using_lists::contract::ListExample::{ - amountsContractMemberStateTrait, tasksContractMemberStateTrait -}; - -fn STATE() -> ListExample::ContractState { - ListExample::contract_state_for_testing() -} - -#[test] -#[available_gas(2000000)] -fn test_add_in_amount() { - let mut state = STATE(); - state.add_in_amount(200); - assert(state.amounts.read()[0] == 200, 'should be 200'); -} - -#[test] -#[available_gas(2000000)] -fn test_add_in_task() { - let mut state = STATE(); - state.add_in_task('test_description', 'test_status'); - let current_task: Task = state.tasks.read()[0]; - assert(current_task.description == 'test_description', 'should be test_description'); - assert(current_task.status == 'test_status', 'should be test_status'); -} - -#[test] -#[available_gas(2000000)] -fn test_is_empty_list() { - let mut state = STATE(); - - let pre_addition = state.is_empty_list(); - assert(pre_addition == true, 'should be true'); - - state.add_in_amount(200); - let post_addition = state.is_empty_list(); - assert(post_addition == false, 'should be false'); -} - -#[test] -#[available_gas(2000000)] -fn test_list_length() { - let mut state = STATE(); - - let pre_addition = state.list_length(); - assert(pre_addition == 0, 'should be zero'); - - state.add_in_amount(200); - let post_addition = state.list_length(); - assert(post_addition == 1, 'should be 1'); -} - -#[test] -#[available_gas(2000000)] -fn test_get_from_index() { - let mut state = STATE(); - state.add_in_amount(200); - let output = state.get_from_index(0); - assert(output == 200, 'should be 200'); -} - -#[test] -#[available_gas(2000000)] -fn test_set_from_index() { - let mut state = STATE(); - state.add_in_amount(200); - state.set_from_index(0, 400); - assert(state.amounts.read()[0] == 400, 'should be 400'); -} - -#[test] -#[available_gas(2000000)] -fn test_pop_front_list() { - let mut state = STATE(); - - state.add_in_amount(200); - let pre_pop_front = state.list_length(); - assert(pre_pop_front == 1, 'should be 1'); - - state.pop_front_list(); - let post_pop_front = state.list_length(); - assert(post_pop_front == 0, 'should be zero'); -} - -#[test] -#[available_gas(2000000)] -fn test_array_conversion() { - let mut ideal_array = ArrayTrait::::new(); - ideal_array.append(200); - ideal_array.append(400); - - let mut state = STATE(); - - state.add_in_amount(200); - state.add_in_amount(400); - let output: Array = state.array_conversion(); - - assert(output == ideal_array, 'should be equal'); -} diff --git a/listings/advanced-concepts/write_to_any_slot/Scarb.toml b/listings/advanced-concepts/write_to_any_slot/Scarb.toml index 7ac53e05..cbad5243 100644 --- a/listings/advanced-concepts/write_to_any_slot/Scarb.toml +++ b/listings/advanced-concepts/write_to_any_slot/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "write_to_any_slot" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/advanced-concepts/write_to_any_slot/src/contract.cairo b/listings/advanced-concepts/write_to_any_slot/src/contract.cairo index 0a08a21b..1e7d4922 100644 --- a/listings/advanced-concepts/write_to_any_slot/src/contract.cairo +++ b/listings/advanced-concepts/write_to_any_slot/src/contract.cairo @@ -35,7 +35,8 @@ pub mod WriteToAnySlot { data.append(variable_name); let hashed_name: felt252 = poseidon_hash_span(data.span()); let MASK_250: u256 = 0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; - // By taking the 250 least significant bits of the hash output, we get a valid 250bits storage address. + // By taking the 250 least significant bits of the hash output, we get a valid 250bits + // storage address. let result: felt252 = (hashed_name.into() & MASK_250).try_into().unwrap(); let result: StorageAddress = result.try_into().unwrap(); result diff --git a/listings/advanced-concepts/write_to_any_slot/src/tests.cairo b/listings/advanced-concepts/write_to_any_slot/src/tests.cairo index 371be462..6428a6eb 100644 --- a/listings/advanced-concepts/write_to_any_slot/src/tests.cairo +++ b/listings/advanced-concepts/write_to_any_slot/src/tests.cairo @@ -7,13 +7,11 @@ trait IWriteToAnySlot { } mod tests { - use super::WriteToAnySlot::get_address_from_name; use super::WriteToAnySlot; use super::{IWriteToAnySlotDispatcher, IWriteToAnySlotDispatcherTrait}; use starknet::syscalls::deploy_syscall; #[test] - #[available_gas(2000000000)] fn test_read_write() { // Set up. let mut calldata: Array = array![]; @@ -29,7 +27,7 @@ mod tests { // Read from slot. let read_value = contract.read_slot(); - assert(read_value == value, 'wrong value read'); + assert_eq!(read_value, value); } } diff --git a/listings/applications/advanced_factory/Scarb.toml b/listings/applications/advanced_factory/Scarb.toml index 5935e01f..825a4654 100644 --- a/listings/applications/advanced_factory/Scarb.toml +++ b/listings/applications/advanced_factory/Scarb.toml @@ -1,15 +1,17 @@ [package] name = "advanced_factory" version.workspace = true -edition = "2023_11" +edition = "2024_07" [dependencies] starknet.workspace = true components.workspace = true -alexandria_storage.workspace = true snforge_std.workspace = true crowdfunding = { path = "../crowdfunding" } +[dev-dependencies] +assert_macros.workspace = true + [scripts] test.workspace = true diff --git a/listings/applications/advanced_factory/src/contract.cairo b/listings/applications/advanced_factory/src/contract.cairo index d3f03432..4c6b4c89 100644 --- a/listings/applications/advanced_factory/src/contract.cairo +++ b/listings/applications/advanced_factory/src/contract.cairo @@ -23,12 +23,14 @@ pub trait ICampaignFactory { pub mod CampaignFactory { use core::num::traits::Zero; use starknet::{ - ContractAddress, ClassHash, SyscallResultTrait, syscalls::deploy_syscall, - get_caller_address, get_contract_address + ContractAddress, ClassHash, SyscallResultTrait, syscalls::deploy_syscall, get_caller_address }; - use alexandria_storage::list::{List, ListTrait}; use crowdfunding::campaign::{ICampaignDispatcher, ICampaignDispatcherTrait}; use components::ownable::ownable_component; + use starknet::storage::{ + Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, + StoragePointerWriteAccess + }; component!(path: ownable_component, storage: ownable, event: OwnableEvent); @@ -41,7 +43,7 @@ pub mod CampaignFactory { #[substorage(v0)] ownable: ownable_component::Storage, /// Store all of the created campaign instances' addresses and thei class hashes - campaigns: LegacyMap<(ContractAddress, ContractAddress), ClassHash>, + campaigns: Map<(ContractAddress, ContractAddress), ClassHash>, /// Store the class hash of the contract to deploy campaign_class_hash: ClassHash, } diff --git a/listings/applications/advanced_factory/src/tests.cairo b/listings/applications/advanced_factory/src/tests.cairo index 437a9f87..759be3d0 100644 --- a/listings/applications/advanced_factory/src/tests.cairo +++ b/listings/applications/advanced_factory/src/tests.cairo @@ -3,26 +3,24 @@ use core::result::ResultTrait; use advanced_factory::contract::{ CampaignFactory, ICampaignFactoryDispatcher, ICampaignFactoryDispatcherTrait }; -use starknet::{ - ContractAddress, ClassHash, get_block_timestamp, contract_address_const, get_caller_address -}; +use crowdfunding::campaign::Campaign; +use starknet::{ClassHash, get_block_timestamp, contract_address_const}; use snforge_std::{ - declare, ContractClass, ContractClassTrait, start_cheat_caller_address, - stop_cheat_caller_address, spy_events, SpyOn, EventSpy, EventAssertions, get_class_hash + declare, start_cheat_caller_address, stop_cheat_caller_address, spy_events, DeclareResultTrait, + ContractClassTrait, get_class_hash, EventSpyAssertionsTrait }; // Define a goal contract to deploy -use crowdfunding::campaign::{Campaign, ICampaignDispatcher, ICampaignDispatcherTrait}; +use crowdfunding::campaign::{ICampaignDispatcher, ICampaignDispatcherTrait}; use components::ownable::{IOwnableDispatcher, IOwnableDispatcherTrait}; - /// Deploy a campaign factory contract with the provided campaign class hash fn deploy_factory_with(campaign_class_hash: ClassHash) -> ICampaignFactoryDispatcher { let mut constructor_calldata: @Array:: = @array![campaign_class_hash.into()]; - let contract = declare("CampaignFactory").unwrap(); + let contract = declare("CampaignFactory").unwrap().contract_class(); let contract_address = contract.precalculate_address(constructor_calldata); - let factory_owner: ContractAddress = contract_address_const::<'factory_owner'>(); + let factory_owner = contract_address_const::<'factory_owner'>(); start_cheat_caller_address(contract_address, factory_owner); contract.deploy(constructor_calldata).unwrap(); @@ -34,18 +32,18 @@ fn deploy_factory_with(campaign_class_hash: ClassHash) -> ICampaignFactoryDispat /// Deploy a campaign factory contract with default campaign class hash fn deploy_factory() -> ICampaignFactoryDispatcher { - let campaign_class_hash = declare("Campaign").unwrap().class_hash; - deploy_factory_with(campaign_class_hash) + let campaign = declare("Campaign").unwrap().contract_class(); + deploy_factory_with(*campaign.class_hash) } #[test] fn test_deploy_factory() { - let campaign_class_hash = declare("Campaign").unwrap().class_hash; - let factory = deploy_factory_with(campaign_class_hash); + let campaign = declare("Campaign").unwrap().contract_class(); + let factory = deploy_factory_with(*campaign.class_hash); - assert_eq!(factory.get_campaign_class_hash(), campaign_class_hash); + assert_eq!(factory.get_campaign_class_hash(), *campaign.class_hash); - let factory_owner: ContractAddress = contract_address_const::<'factory_owner'>(); + let factory_owner = contract_address_const::<'factory_owner'>(); let factory_ownable = IOwnableDispatcher { contract_address: factory.contract_address }; assert_eq!(factory_ownable.owner(), factory_owner); } @@ -54,9 +52,9 @@ fn test_deploy_factory() { fn test_create_campaign() { let factory = deploy_factory(); - let mut spy = spy_events(SpyOn::One(factory.contract_address)); + let mut spy = spy_events(); - let campaign_creator: ContractAddress = contract_address_const::<'campaign_creator'>(); + let campaign_creator = contract_address_const::<'campaign_creator'>(); start_cheat_caller_address(factory.contract_address, campaign_creator); let title: ByteArray = "New campaign"; @@ -104,7 +102,7 @@ fn test_create_campaign() { fn test_uprade_campaign_class_hash() { let factory = deploy_factory(); let old_class_hash = factory.get_campaign_class_hash(); - let new_class_hash = declare("MockContract").unwrap().class_hash; + let new_class_hash = *declare("MockContract").unwrap().contract_class().class_hash; let token = contract_address_const::<'token'>(); @@ -133,9 +131,7 @@ fn test_uprade_campaign_class_hash() { assert_eq!(old_class_hash, get_class_hash(active_campaign)); // update the factory's campaign class hash value - let mut spy = spy_events( - SpyOn::Multiple(array![factory.contract_address, pending_campaign, active_campaign]) - ); + let mut spy = spy_events(); let factory_owner = contract_address_const::<'factory_owner'>(); start_cheat_caller_address(factory.contract_address, factory_owner); diff --git a/listings/applications/components/Scarb.toml b/listings/applications/components/Scarb.toml index 3e1f13a1..afa1fd51 100644 --- a/listings/applications/components/Scarb.toml +++ b/listings/applications/components/Scarb.toml @@ -1,13 +1,16 @@ [package] name = "components" version.workspace = true -edition = '2023_11' +edition = "2024_07" [lib] [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/applications/components/src/countable.cairo b/listings/applications/components/src/countable.cairo index 6ca26c63..141fe06d 100644 --- a/listings/applications/components/src/countable.cairo +++ b/listings/applications/components/src/countable.cairo @@ -7,8 +7,10 @@ pub trait ICountable { #[starknet::component] pub mod countable_component { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + #[storage] - struct Storage { + pub struct Storage { countable_value: u32, } diff --git a/listings/applications/components/src/others/switch_collision.cairo b/listings/applications/components/src/others/switch_collision.cairo index 58b2973f..ee34f1e1 100644 --- a/listings/applications/components/src/others/switch_collision.cairo +++ b/listings/applications/components/src/others/switch_collision.cairo @@ -9,6 +9,7 @@ pub trait ISwitchCollision { #[starknet::contract] pub mod SwitchCollisionContract { use components::switchable::switchable_component; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; component!(path: switchable_component, storage: switch, event: SwitchableEvent); @@ -50,12 +51,10 @@ pub mod SwitchCollisionContract { #[cfg(test)] mod switch_collision_tests { - use components::switchable::switchable_component::SwitchableInternalTrait; - use components::switchable::{ISwitchable, ISwitchableDispatcher, ISwitchableDispatcherTrait}; + use components::switchable::{ISwitchableDispatcher, ISwitchableDispatcherTrait}; use super::{ SwitchCollisionContract, ISwitchCollisionDispatcher, ISwitchCollisionDispatcherTrait }; - use starknet::storage::StorageMemberAccessTrait; use starknet::SyscallResultTrait; use starknet::syscalls::deploy_syscall; @@ -89,5 +88,5 @@ mod switch_collision_tests { contract.set(false); assert_eq!(contract.get(), contract_iswitch.is_on()); } -// ANCHOR_END: collision + // ANCHOR_END: collision } diff --git a/listings/applications/components/src/ownable.cairo b/listings/applications/components/src/ownable.cairo index e827c741..45d8457c 100644 --- a/listings/applications/components/src/ownable.cairo +++ b/listings/applications/components/src/ownable.cairo @@ -19,9 +19,10 @@ pub mod ownable_component { use super::Errors; use starknet::{ContractAddress, get_caller_address}; use core::num::traits::Zero; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; #[storage] - struct Storage { + pub struct Storage { ownable_owner: ContractAddress, } @@ -99,7 +100,7 @@ pub mod ownable_component { // ANCHOR: contract #[starknet::contract] pub mod OwnedContract { - use super::{IOwnable, ownable_component, ownable_component::OwnableInternalTrait}; + use super::{ownable_component, ownable_component::OwnableInternalTrait}; component!(path: ownable_component, storage: ownable, event: OwnableEvent); @@ -128,12 +129,11 @@ pub mod OwnedContract { #[cfg(test)] mod test { use super::OwnedContract; - use super::ownable_component::{Event, OwnershipRenouncedEvent, OwnershipTransferredEvent}; + use super::ownable_component::{OwnershipRenouncedEvent, OwnershipTransferredEvent}; use super::{IOwnableDispatcher, IOwnableDispatcherTrait}; - use super::Errors; use starknet::ContractAddress; use starknet::{syscalls::deploy_syscall, SyscallResultTrait, contract_address_const}; - use starknet::testing::{set_caller_address, set_contract_address}; + use starknet::testing::{set_contract_address}; use core::num::traits::Zero; fn deploy() -> (IOwnableDispatcher, ContractAddress) { diff --git a/listings/applications/components/src/switchable.cairo b/listings/applications/components/src/switchable.cairo index e58096df..75fa0555 100644 --- a/listings/applications/components/src/switchable.cairo +++ b/listings/applications/components/src/switchable.cairo @@ -9,8 +9,10 @@ pub trait ISwitchable { #[starknet::component] pub mod switchable_component { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + #[storage] - struct Storage { + pub struct Storage { switchable_value: bool, } @@ -85,9 +87,9 @@ pub mod SwitchContract { #[cfg(test)] mod test { use super::SwitchContract; // Used as a mock contract - use super::switchable_component::{Event, SwitchEvent}; + use super::switchable_component::SwitchEvent; use super::{ISwitchableDispatcher, ISwitchableDispatcherTrait}; - use starknet::{syscalls::deploy_syscall, contract_address_const, ContractAddress}; + use starknet::{syscalls::deploy_syscall, ContractAddress}; use starknet::SyscallResultTrait; fn deploy() -> (ISwitchableDispatcher, ContractAddress) { diff --git a/listings/applications/components_dependencies/Scarb.toml b/listings/applications/components_dependencies/Scarb.toml index 4864600d..27d39111 100644 --- a/listings/applications/components_dependencies/Scarb.toml +++ b/listings/applications/components_dependencies/Scarb.toml @@ -1,12 +1,15 @@ [package] name = "components_dependencies" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true components = { path = "../components" } +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/applications/components_dependencies/src/contract_countable.cairo b/listings/applications/components_dependencies/src/contract_countable.cairo index fd813427..bb587b36 100644 --- a/listings/applications/components_dependencies/src/contract_countable.cairo +++ b/listings/applications/components_dependencies/src/contract_countable.cairo @@ -1,6 +1,7 @@ // ANCHOR: contract #[starknet::contract] mod CountableContract { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use components_dependencies::countable_dep_switch::countable_component; use components::switchable::ISwitchable; @@ -44,10 +45,9 @@ mod CountableContract { #[cfg(test)] mod tests { use super::CountableContract; - use components::countable::{ICountable, ICountableDispatcher, ICountableDispatcherTrait}; - use components::switchable::{ISwitchable, ISwitchableDispatcher, ISwitchableDispatcherTrait}; + use components::countable::{ICountableDispatcher, ICountableDispatcherTrait}; + use components::switchable::{ISwitchableDispatcher, ISwitchableDispatcherTrait}; - use starknet::storage::StorageMemberAccessTrait; use starknet::SyscallResultTrait; use starknet::syscalls::deploy_syscall; @@ -61,38 +61,34 @@ mod tests { } #[test] - #[available_gas(2000000)] fn test_init() { let (mut counter, mut switch) = deploy(); - assert(counter.get() == 0, 'Counter != 0'); - assert(switch.is_on() == false, 'Switch != false'); + assert_eq!(counter.get(), 0); + assert_eq!(switch.is_on(), false); } #[test] - #[available_gas(2000000)] fn test_increment_switch_off() { let (mut counter, mut switch) = deploy(); counter.increment(); - assert(counter.get() == 0, 'Counter incremented'); - assert(switch.is_on() == false, 'Switch != false'); + assert_eq!(counter.get(), 0); + assert_eq!(switch.is_on(), false); } #[test] - #[available_gas(2000000)] fn test_increment_switch_on() { let (mut counter, mut switch) = deploy(); switch.switch(); - assert(switch.is_on() == true, 'Switch != true'); + assert_eq!(switch.is_on(), true); counter.increment(); - assert(counter.get() == 1, 'Counter did not increment'); + assert_eq!(counter.get(), 1); } #[test] - #[available_gas(2000000)] fn test_increment_multiple_switches() { let (mut counter, mut switch) = deploy(); @@ -101,7 +97,7 @@ mod tests { counter.increment(); counter.increment(); counter.increment(); - assert(counter.get() == 3, 'Counter did not increment'); + assert_eq!(counter.get(), 3); switch.switch(); counter.increment(); @@ -113,6 +109,6 @@ mod tests { counter.increment(); counter.increment(); counter.increment(); - assert(counter.get() == 6, 'Counter did not increment'); + assert_eq!(counter.get(), 6); } } diff --git a/listings/applications/components_dependencies/src/contract_countable_switchable.cairo b/listings/applications/components_dependencies/src/contract_countable_switchable.cairo index 9ef201fa..fdf8df55 100644 --- a/listings/applications/components_dependencies/src/contract_countable_switchable.cairo +++ b/listings/applications/components_dependencies/src/contract_countable_switchable.cairo @@ -38,10 +38,9 @@ mod CountableContract { #[cfg(test)] mod tests { use super::CountableContract; - use components::countable::{ICountable, ICountableDispatcher, ICountableDispatcherTrait}; - use components::switchable::{ISwitchable, ISwitchableDispatcher, ISwitchableDispatcherTrait}; + use components::countable::{ICountableDispatcher, ICountableDispatcherTrait}; + use components::switchable::{ISwitchableDispatcher, ISwitchableDispatcherTrait}; - use starknet::storage::StorageMemberAccessTrait; use starknet::SyscallResultTrait; use starknet::syscalls::deploy_syscall; @@ -55,38 +54,34 @@ mod tests { } #[test] - #[available_gas(2000000)] fn test_init() { let (mut counter, mut switch) = deploy(); - assert(counter.get() == 0, 'Counter != 0'); - assert(switch.is_on() == false, 'Switch != false'); + assert_eq!(counter.get(), 0); + assert_eq!(switch.is_on(), false); } #[test] - #[available_gas(2000000)] fn test_increment_switch_off() { let (mut counter, mut switch) = deploy(); counter.increment(); - assert(counter.get() == 0, 'Counter incremented'); - assert(switch.is_on() == false, 'Switch != false'); + assert_eq!(counter.get(), 0); + assert_eq!(switch.is_on(), false); } #[test] - #[available_gas(2000000)] fn test_increment_switch_on() { let (mut counter, mut switch) = deploy(); switch.switch(); - assert(switch.is_on() == true, 'Switch != true'); + assert_eq!(switch.is_on(), true); counter.increment(); - assert(counter.get() == 1, 'Counter did not increment'); + assert_eq!(counter.get(), 1); } #[test] - #[available_gas(3000000)] fn test_increment_multiple_switches() { let (mut counter, mut switch) = deploy(); @@ -95,7 +90,7 @@ mod tests { counter.increment(); counter.increment(); counter.increment(); - assert(counter.get() == 3, 'Counter did not increment'); + assert_eq!(counter.get(), 3); switch.switch(); counter.increment(); @@ -107,6 +102,6 @@ mod tests { counter.increment(); counter.increment(); counter.increment(); - assert(counter.get() == 6, 'Counter did not increment'); + assert_eq!(counter.get(), 6); } } diff --git a/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo b/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo index e52f3cb1..bfc64933 100644 --- a/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo +++ b/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo @@ -38,10 +38,9 @@ pub mod CountableContract { #[cfg(test)] mod tests { use super::CountableContract; - use components::countable::{ICountable, ICountableDispatcher, ICountableDispatcherTrait}; - use components::switchable::{ISwitchable, ISwitchableDispatcher, ISwitchableDispatcherTrait}; + use components::countable::{ICountableDispatcher, ICountableDispatcherTrait}; + use components::switchable::{ISwitchableDispatcher, ISwitchableDispatcherTrait}; - use starknet::storage::StorageMemberAccessTrait; use starknet::SyscallResultTrait; use starknet::syscalls::deploy_syscall; @@ -55,41 +54,37 @@ mod tests { } #[test] - #[available_gas(2000000)] fn test_init() { let (mut counter, mut switch) = deploy(); - assert(counter.get() == 0, 'Counter != 0'); - assert(switch.is_on() == false, 'Switch != false'); + assert_eq!(counter.get(), 0); + assert_eq!(switch.is_on(), false); } #[test] - #[available_gas(2000000)] fn test_increment_switch_off() { let (mut counter, mut switch) = deploy(); counter.increment(); - assert(counter.get() == 0, 'Counter incremented'); - assert(switch.is_on() == false, 'Switch != false'); + assert_eq!(counter.get(), 0); + assert_eq!(switch.is_on(), false); } #[test] - #[available_gas(2000000)] fn test_increment_switch_on() { let (mut counter, mut switch) = deploy(); switch.switch(); - assert(switch.is_on() == true, 'Switch != true'); + assert_eq!(switch.is_on(), true); counter.increment(); - assert(counter.get() == 1, 'Counter did not increment'); + assert_eq!(counter.get(), 1); // The counter turned the switch off. - assert(switch.is_on() == false, 'Switch != false'); + assert_eq!(switch.is_on(), false); } #[test] - #[available_gas(3000000)] fn test_increment_multiple_switches() { let (mut counter, mut switch) = deploy(); @@ -98,13 +93,13 @@ mod tests { counter.increment(); counter.increment(); // off counter.increment(); // off - assert(counter.get() == 1, 'Counter did not increment'); + assert_eq!(counter.get(), 1); switch.switch(); counter.increment(); switch.switch(); counter.increment(); counter.increment(); - assert(counter.get() == 3, 'Counter did not increment'); + assert_eq!(counter.get(), 3); } } diff --git a/listings/applications/components_dependencies/src/countable_dep_switch.cairo b/listings/applications/components_dependencies/src/countable_dep_switch.cairo index 762470e5..4cc2a1a6 100644 --- a/listings/applications/components_dependencies/src/countable_dep_switch.cairo +++ b/listings/applications/components_dependencies/src/countable_dep_switch.cairo @@ -1,11 +1,12 @@ // ANCHOR: contract #[starknet::component] pub mod countable_component { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use components::countable::ICountable; use components::switchable::ISwitchable; #[storage] - struct Storage { + pub struct Storage { countable_value: u32, } @@ -24,7 +25,7 @@ pub mod countable_component { } } } -// ANCHOR_END: impl + // ANCHOR_END: impl } //ANCHOR_END: contract diff --git a/listings/applications/components_dependencies/src/countable_internal_dep_switch.cairo b/listings/applications/components_dependencies/src/countable_internal_dep_switch.cairo index bfa5e020..b5f47720 100644 --- a/listings/applications/components_dependencies/src/countable_internal_dep_switch.cairo +++ b/listings/applications/components_dependencies/src/countable_internal_dep_switch.cairo @@ -1,6 +1,7 @@ //ANCHOR: contract #[starknet::component] pub mod countable_component { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use components::countable::ICountable; use components::switchable::ISwitchable; @@ -9,7 +10,7 @@ pub mod countable_component { use switchable_component::{SwitchableInternalImpl, SwitchableInternalTrait}; #[storage] - struct Storage { + pub struct Storage { countable_value: u32, } diff --git a/listings/applications/constant_product_amm/Scarb.toml b/listings/applications/constant_product_amm/Scarb.toml index 17a77276..4a798451 100644 --- a/listings/applications/constant_product_amm/Scarb.toml +++ b/listings/applications/constant_product_amm/Scarb.toml @@ -1,12 +1,15 @@ [package] name = "constant_product_amm" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true openzeppelin.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/applications/constant_product_amm/src/contracts.cairo b/listings/applications/constant_product_amm/src/contracts.cairo index 5ac44d74..9b6ebfa4 100644 --- a/listings/applications/constant_product_amm/src/contracts.cairo +++ b/listings/applications/constant_product_amm/src/contracts.cairo @@ -10,11 +10,11 @@ pub trait IConstantProductAmm { #[starknet::contract] pub mod ConstantProductAmm { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; - use starknet::{ - ContractAddress, get_caller_address, get_contract_address, contract_address_const - }; - use core::integer::u256_sqrt; + use starknet::{ContractAddress, get_caller_address, get_contract_address}; + use starknet::storage::{Map, StorageMapReadAccess, StorageMapWriteAccess}; + use core::num::traits::Sqrt; #[storage] struct Storage { @@ -23,7 +23,7 @@ pub mod ConstantProductAmm { reserve0: u256, reserve1: u256, total_supply: u256, - balance_of: LegacyMap::, + balance_of: Map::, // Fee 0 - 1000 (0% - 100%, 1 decimal places) // E.g. 3 = 0.3% fee: u16, @@ -193,7 +193,7 @@ pub mod ConstantProductAmm { let total_supply = self.total_supply.read(); let shares = if (total_supply == 0) { - u256_sqrt(amount0 * amount1).into() + (amount0 * amount1).sqrt().into() } else { PrivateFunctions::min( amount0 * total_supply / reserve0, amount1 * total_supply / reserve1 diff --git a/listings/applications/constant_product_amm/src/tests.cairo b/listings/applications/constant_product_amm/src/tests.cairo index a94d111c..7a87e616 100644 --- a/listings/applications/constant_product_amm/src/tests.cairo +++ b/listings/applications/constant_product_amm/src/tests.cairo @@ -38,7 +38,8 @@ pub mod ERC20Token { // Wait for OZ #953 fix // mod tests { // use super::ERC20Token; -// use openzeppelin::token::erc20::{interface::IERC20Dispatcher, interface::IERC20DispatcherTrait}; +// use openzeppelin::token::erc20::{interface::IERC20Dispatcher, +// interface::IERC20DispatcherTrait}; // use openzeppelin::tests::utils; // use openzeppelin::utils::serde::SerializedAppend; @@ -93,7 +94,8 @@ pub mod ERC20Token { // .unwrap(); // // Or with OpenZeppelin helper: // // let contract_address = utils::deploy(ConstantProductAmm::TEST_CLASS_HASH, calldata); -// Deployment { contract: IConstantProductAmmDispatcher { contract_address }, token0, token1 } +// Deployment { contract: IConstantProductAmmDispatcher { contract_address }, token0, token1 +// } // } // fn add_liquidity(deploy: Deployment, amount: u256) -> u256 { diff --git a/listings/applications/crowdfunding/Scarb.toml b/listings/applications/crowdfunding/Scarb.toml index 074a2713..744ae4d2 100644 --- a/listings/applications/crowdfunding/Scarb.toml +++ b/listings/applications/crowdfunding/Scarb.toml @@ -1,7 +1,7 @@ [package] name = "crowdfunding" version.workspace = true -edition = "2023_11" +edition = "2024_07" [lib] @@ -11,9 +11,11 @@ openzeppelin.workspace = true components.workspace = true snforge_std.workspace = true +[dev-dependencies] +assert_macros.workspace = true + [scripts] test.workspace = true [[target.starknet-contract]] -casm = true -build-external-contracts = ["openzeppelin::presets::erc20::ERC20Upgradeable"] +build-external-contracts = ["openzeppelin_presets::erc20::ERC20Upgradeable"] diff --git a/listings/applications/crowdfunding/src/campaign.cairo b/listings/applications/crowdfunding/src/campaign.cairo index c8892de0..e4f0b375 100644 --- a/listings/applications/crowdfunding/src/campaign.cairo +++ b/listings/applications/crowdfunding/src/campaign.cairo @@ -32,12 +32,13 @@ pub trait ICampaign { #[starknet::contract] pub mod Campaign { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use components::ownable::ownable_component::OwnableInternalTrait; use core::num::traits::Zero; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use starknet::{ - ClassHash, ContractAddress, SyscallResultTrait, get_block_timestamp, contract_address_const, - get_caller_address, get_contract_address, class_hash::class_hash_const + ClassHash, ContractAddress, SyscallResultTrait, get_block_timestamp, get_caller_address, + get_contract_address }; use components::ownable::ownable_component; use super::pledgeable::pledgeable_component; @@ -154,7 +155,7 @@ pub mod Campaign { pub const ZERO_PLEDGES: felt252 = 'No pledges to claim'; } - const NINETY_DAYS: u64 = consteval_int!(90 * 24 * 60 * 60); + const NINETY_DAYS: u64 = 90 * 24 * 60 * 60; #[constructor] fn constructor( diff --git a/listings/applications/crowdfunding/src/campaign/pledgeable.cairo b/listings/applications/crowdfunding/src/campaign/pledgeable.cairo index 4000057a..c90290d8 100644 --- a/listings/applications/crowdfunding/src/campaign/pledgeable.cairo +++ b/listings/applications/crowdfunding/src/campaign/pledgeable.cairo @@ -14,13 +14,17 @@ pub trait IPledgeable { #[starknet::component] pub mod pledgeable_component { use core::array::ArrayTrait; - use starknet::{ContractAddress}; use core::num::traits::Zero; + use starknet::ContractAddress; + use starknet::storage::{ + Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, + StoragePointerWriteAccess + }; #[storage] - struct Storage { - index_to_pledger: LegacyMap, - pledger_to_amount: LegacyMap, + pub struct Storage { + index_to_pledger: Map, + pledger_to_amount: Map, pledger_count: u32, total_amount: u256, } @@ -137,8 +141,8 @@ mod tests { impl Pledgeable = pledgeable_component::Pledgeable; } - use super::{pledgeable_component, IPledgeableDispatcher, IPledgeableDispatcherTrait}; - use super::pledgeable_component::{PledgeableImpl}; + use super::pledgeable_component; + use super::pledgeable_component::PledgeableImpl; use starknet::{ContractAddress, contract_address_const}; use core::num::traits::Zero; @@ -209,10 +213,9 @@ mod tests { assert_eq!(pledgeable.get_pledger_count(), expected_pledger_count); assert_eq!(pledgeable.get_total(), expected_total); - while let Option::Some((pledger, expected_amount)) = pledgers - .pop_front() { - assert_eq!(pledgeable.get(pledger), expected_amount); - } + while let Option::Some((pledger, expected_amount)) = pledgers.pop_front() { + assert_eq!(pledgeable.get(pledger), expected_amount); + } } #[test] @@ -466,7 +469,7 @@ mod tests { i -= 1; }; - // add last pledger + // add last pledger pledgeable.add(last_pledger, last_amount); expected_total += last_amount; @@ -528,13 +531,12 @@ mod tests { assert_eq!(pledgers_arr.len(), pledgers.len()); let mut i = 1000; - while let Option::Some(expected_pledger) = pledgers - .pop_front() { - i -= 1; - // pledgers are fetched in reversed order - let actual_pledger: ContractAddress = *pledgers_arr.at(i); - assert_eq!(expected_pledger, actual_pledger); - } + while let Option::Some(expected_pledger) = pledgers.pop_front() { + i -= 1; + // pledgers are fetched in reversed order + let actual_pledger: ContractAddress = *pledgers_arr.at(i); + assert_eq!(expected_pledger, actual_pledger); + } } #[test] diff --git a/listings/applications/crowdfunding/src/mock_upgrade.cairo b/listings/applications/crowdfunding/src/mock_upgrade.cairo index 27e9f1b5..de4c5e60 100644 --- a/listings/applications/crowdfunding/src/mock_upgrade.cairo +++ b/listings/applications/crowdfunding/src/mock_upgrade.cairo @@ -1,11 +1,12 @@ #[starknet::contract] pub mod MockUpgrade { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use components::ownable::ownable_component::OwnableInternalTrait; use core::num::traits::Zero; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; use starknet::{ - ClassHash, ContractAddress, SyscallResultTrait, get_block_timestamp, contract_address_const, - get_caller_address, get_contract_address, class_hash::class_hash_const + ClassHash, ContractAddress, SyscallResultTrait, get_block_timestamp, get_caller_address, + get_contract_address }; use components::ownable::ownable_component; use crowdfunding::campaign::pledgeable::pledgeable_component; @@ -95,7 +96,7 @@ pub mod MockUpgrade { pub implementation: ClassHash } - const NINETY_DAYS: u64 = consteval_int!(90 * 24 * 60 * 60); + const NINETY_DAYS: u64 = 90 * 24 * 60 * 60; #[constructor] fn constructor( diff --git a/listings/applications/crowdfunding/src/tests.cairo b/listings/applications/crowdfunding/src/tests.cairo index 6aff05d8..ba01cf83 100644 --- a/listings/applications/crowdfunding/src/tests.cairo +++ b/listings/applications/crowdfunding/src/tests.cairo @@ -1,12 +1,9 @@ -use core::clone::Clone; use core::result::ResultTrait; -use starknet::{ - ContractAddress, ClassHash, get_block_timestamp, contract_address_const, get_caller_address, -}; +use starknet::{ContractAddress, get_block_timestamp, contract_address_const,}; use snforge_std::{ declare, ContractClass, ContractClassTrait, start_cheat_caller_address, - stop_cheat_caller_address, spy_events, SpyOn, EventSpy, EventAssertions, get_class_hash, - cheat_block_timestamp_global + stop_cheat_caller_address, spy_events, EventSpyAssertionsTrait, get_class_hash, + DeclareResultTrait, start_cheat_block_timestamp_global }; use crowdfunding::campaign::{Campaign, ICampaignDispatcher, ICampaignDispatcherTrait}; @@ -92,7 +89,7 @@ fn deploy_with_token( fn test_deploy() { let start_time = get_block_timestamp(); let end_time = start_time + 60; - let contract = declare("Campaign").unwrap(); + let contract = *declare("Campaign").unwrap().contract_class(); let campaign = deploy( contract, "title 1", @@ -122,8 +119,8 @@ fn test_deploy() { #[test] fn test_successful_campaign() { - let token_class = declare("ERC20Upgradeable").unwrap(); - let contract_class = declare("Campaign").unwrap(); + let token_class = *declare("ERC20Upgradeable").unwrap().contract_class(); + let contract_class = *declare("Campaign").unwrap().contract_class(); let (campaign, token) = deploy_with_token(contract_class, token_class); let creator = contract_address_const::<'creator'>(); @@ -131,7 +128,7 @@ fn test_successful_campaign() { let pledger_2 = contract_address_const::<'pledger_2'>(); let pledger_3 = contract_address_const::<'pledger_3'>(); - let mut spy = spy_events(SpyOn::One(campaign.contract_address)); + let mut spy = spy_events(); // 1st donation start_cheat_caller_address(campaign.contract_address, pledger_1); @@ -193,8 +190,8 @@ fn test_successful_campaign() { ] ); - // claim - cheat_block_timestamp_global(campaign.get_details().end_time); + // claim + start_cheat_block_timestamp_global(campaign.get_details().end_time); start_cheat_caller_address(campaign.contract_address, creator); prev_balance = token.balance_of(creator); campaign.claim(); @@ -214,14 +211,14 @@ fn test_successful_campaign() { #[test] fn test_upgrade_class_hash() { - let new_class_hash = declare("MockUpgrade").unwrap().class_hash; + let new_class_hash = *(declare("MockUpgrade").unwrap().contract_class()).class_hash; let owner = contract_address_const::<'owner'>(); // test pending campaign - let contract_class = declare("Campaign").unwrap(); - let token_class = declare("ERC20Upgradeable").unwrap(); + let contract_class = *declare("Campaign").unwrap().contract_class(); + let token_class = *declare("ERC20Upgradeable").unwrap().contract_class(); let (campaign, _) = deploy_with_token(contract_class, token_class); - let mut spy = spy_events(SpyOn::One(campaign.contract_address)); + let mut spy = spy_events(); start_cheat_caller_address(campaign.contract_address, owner); campaign.upgrade(new_class_hash, Option::None); @@ -241,7 +238,7 @@ fn test_upgrade_class_hash() { // test active campaign let (campaign, token) = deploy_with_token(contract_class, token_class); - let mut spy = spy_events(SpyOn::One(campaign.contract_address)); + let mut spy = spy_events(); let duration: u64 = 60; let pledger_1 = contract_address_const::<'pledger_1'>(); let pledger_2 = contract_address_const::<'pledger_2'>(); @@ -286,12 +283,12 @@ fn test_upgrade_class_hash() { #[test] fn test_cancel() { - let contract_class = declare("Campaign").unwrap(); - let token_class = declare("ERC20Upgradeable").unwrap(); + let contract_class = *declare("Campaign").unwrap().contract_class(); + let token_class = *declare("ERC20Upgradeable").unwrap().contract_class(); // test canceled campaign let (campaign, token) = deploy_with_token(contract_class, token_class); - let mut spy = spy_events(SpyOn::One(campaign.contract_address)); + let mut spy = spy_events(); let creator = contract_address_const::<'creator'>(); let pledger_1 = contract_address_const::<'pledger_1'>(); let pledger_2 = contract_address_const::<'pledger_2'>(); @@ -340,7 +337,7 @@ fn test_cancel() { // test failed campaign let (campaign, token) = deploy_with_token(contract_class, token_class); - let mut spy = spy_events(SpyOn::One(campaign.contract_address)); + let mut spy = spy_events(); let creator = contract_address_const::<'creator'>(); let pledger_1 = contract_address_const::<'pledger_1'>(); let pledger_2 = contract_address_const::<'pledger_2'>(); @@ -363,7 +360,7 @@ fn test_cancel() { assert_eq!(token.balance_of(pledger_2), prev_balance_pledger_2 - pledge_2); assert_eq!(token.balance_of(pledger_3), prev_balance_pledger_3 - pledge_3); - cheat_block_timestamp_global(campaign.get_details().end_time); + start_cheat_block_timestamp_global(campaign.get_details().end_time); start_cheat_caller_address(campaign.contract_address, creator); campaign.cancel("testing"); @@ -394,9 +391,10 @@ fn test_cancel() { fn test_refund() { // setup let (campaign, token) = deploy_with_token( - declare("Campaign").unwrap(), declare("ERC20Upgradeable").unwrap() + *declare("Campaign").unwrap().contract_class(), + *declare("ERC20Upgradeable").unwrap().contract_class() ); - let mut spy = spy_events(SpyOn::One(campaign.contract_address)); + let mut spy = spy_events(); let creator = contract_address_const::<'creator'>(); let pledger_1 = contract_address_const::<'pledger_1'>(); let pledger_2 = contract_address_const::<'pledger_2'>(); @@ -445,9 +443,10 @@ fn test_refund() { fn test_unpledge() { // setup let (campaign, token) = deploy_with_token( - declare("Campaign").unwrap(), declare("ERC20Upgradeable").unwrap() + *declare("Campaign").unwrap().contract_class(), + *declare("ERC20Upgradeable").unwrap().contract_class() ); - let mut spy = spy_events(SpyOn::One(campaign.contract_address)); + let mut spy = spy_events(); let pledger = contract_address_const::<'pledger_1'>(); let amount: u256 = 3000; let prev_balance = token.balance_of(pledger); diff --git a/listings/applications/erc20/Scarb.toml b/listings/applications/erc20/Scarb.toml index e54db3f0..81a90227 100644 --- a/listings/applications/erc20/Scarb.toml +++ b/listings/applications/erc20/Scarb.toml @@ -1,13 +1,16 @@ [package] name = "erc20" version.workspace = true -edition = '2023_11' +edition = "2024_07" [lib] [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/applications/erc20/src/token.cairo b/listings/applications/erc20/src/token.cairo index c2477789..69370439 100644 --- a/listings/applications/erc20/src/token.cairo +++ b/listings/applications/erc20/src/token.cairo @@ -33,6 +33,10 @@ pub mod erc20 { use starknet::get_caller_address; use starknet::contract_address_const; use starknet::ContractAddress; + use starknet::storage::{ + Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, + StoragePointerWriteAccess + }; #[storage] struct Storage { @@ -40,8 +44,8 @@ pub mod erc20 { symbol: felt252, decimals: u8, total_supply: felt252, - balances: LegacyMap::, - allowances: LegacyMap::<(ContractAddress, ContractAddress), felt252>, + balances: Map::, + allowances: Map::<(ContractAddress, ContractAddress), felt252>, } #[event] @@ -217,12 +221,11 @@ mod tests { use super::{erc20, IERC20Dispatcher, IERC20DispatcherTrait, erc20::{Event, Transfer, Approval}}; use starknet::{ - ContractAddress, SyscallResultTrait, syscalls::deploy_syscall, get_caller_address, - contract_address_const + ContractAddress, SyscallResultTrait, syscalls::deploy_syscall, contract_address_const }; use core::num::traits::Zero; - use starknet::testing::{set_contract_address, set_account_contract_address}; + use starknet::testing::set_contract_address; const token_name: felt252 = 'myToken'; const decimals: u8 = 18; diff --git a/listings/applications/nft_dutch_auction/Scarb.toml b/listings/applications/nft_dutch_auction/Scarb.toml index a6af238d..fea2ffae 100644 --- a/listings/applications/nft_dutch_auction/Scarb.toml +++ b/listings/applications/nft_dutch_auction/Scarb.toml @@ -1,14 +1,15 @@ [package] name = "nft_dutch_auction" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] erc20 = { path = "../erc20" } starknet.workspace = true +snforge_std.workspace = true [dev-dependencies] -snforge_std.workspace = true +assert_macros.workspace = true [scripts] test.workspace = true diff --git a/listings/applications/nft_dutch_auction/src/erc721.cairo b/listings/applications/nft_dutch_auction/src/erc721.cairo index 51ec11b6..b18c6a05 100644 --- a/listings/applications/nft_dutch_auction/src/erc721.cairo +++ b/listings/applications/nft_dutch_auction/src/erc721.cairo @@ -25,6 +25,10 @@ mod ERC721 { // library imports //////////////////////////////// use starknet::{ContractAddress, get_caller_address}; + use starknet::storage::{ + Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, + StoragePointerWriteAccess + }; use core::num::traits::Zero; //////////////////////////////// @@ -34,11 +38,11 @@ mod ERC721 { struct Storage { name: felt252, symbol: felt252, - owners: LegacyMap::, - balances: LegacyMap::, - token_approvals: LegacyMap::, - operator_approvals: LegacyMap::<(ContractAddress, ContractAddress), bool>, - token_uri: LegacyMap, + owners: Map::, + balances: Map::, + token_approvals: Map::, + operator_approvals: Map::<(ContractAddress, ContractAddress), bool>, + token_uri: Map, } #[event] @@ -162,7 +166,7 @@ mod ERC721 { } //////////////////////////////// - // set_approval_for_all function approves an operator to spend all tokens + // set_approval_for_all function approves an operator to spend all tokens //////////////////////////////// fn set_approval_for_all( ref self: ContractState, operator: ContractAddress, approved: bool diff --git a/listings/applications/nft_dutch_auction/src/nft_dutch_auction.cairo b/listings/applications/nft_dutch_auction/src/nft_dutch_auction.cairo index aa85dd80..f139c2b1 100644 --- a/listings/applications/nft_dutch_auction/src/nft_dutch_auction.cairo +++ b/listings/applications/nft_dutch_auction/src/nft_dutch_auction.cairo @@ -53,7 +53,8 @@ pub trait INFTDutchAuction { #[starknet::contract] pub mod NFTDutchAuction { use super::{IERC20Dispatcher, IERC20DispatcherTrait, IERC721Dispatcher, IERC721DispatcherTrait}; - use starknet::{ContractAddress, get_caller_address, get_contract_address, get_block_timestamp}; + use starknet::{ContractAddress, get_caller_address, get_block_timestamp}; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; #[storage] struct Storage { @@ -140,7 +141,7 @@ pub mod NFTDutchAuction { mod tests { use starknet::ContractAddress; use snforge_std::{ - BlockId, declare, ContractClassTrait, ContractClass, cheat_caller_address, CheatSpan, + declare, DeclareResultTrait, ContractClassTrait, cheat_caller_address, CheatSpan, cheat_block_timestamp }; use nft_dutch_auction::erc721::{IERC721Dispatcher, IERC721DispatcherTrait}; @@ -166,10 +167,10 @@ mod tests { pub const total_supply: felt252 = 2; fn get_contract_addresses() -> (ContractAddress, ContractAddress, ContractAddress) { - let erc721 = declare("ERC721").unwrap(); + let erc721 = declare("ERC721").unwrap().contract_class(); let erc721_constructor_calldata = array![erc721_name, erc721_symbol]; let (erc721_address, _) = erc721.deploy(@erc721_constructor_calldata).unwrap(); - let erc20 = declare("erc20").unwrap(); + let erc20 = declare("erc20").unwrap().contract_class(); let erc20_constructor_calldata = array![ erc20_recipient, erc20_name, @@ -178,7 +179,7 @@ mod tests { erc20_symbol ]; let (erc20_address, _) = erc20.deploy(@erc20_constructor_calldata).unwrap(); - let nft_auction = declare("NFTDutchAuction").unwrap(); + let nft_auction = declare("NFTDutchAuction").unwrap().contract_class(); let nft_auction_constructor_calldata = array![ erc20_address.into(), erc721_address.into(), @@ -234,7 +235,7 @@ mod tests { assert_eq!(buyer_bal_after_buy, buyer_bal_before_buy - nft_price); assert_eq!(erc721_dispatcher.owner_of(nft_id_1), buyer); - // Forward block timestamp in order for a reduced nft price + // Forward block timestamp in order for a reduced nft price let forward_blocktime_by = 4000; // milliseconds cheat_block_timestamp(nft_auction_address, forward_blocktime_by, CheatSpan::TargetCalls(1)); @@ -276,7 +277,7 @@ mod tests { erc20_dispatcher.approve(nft_auction_address, nft_price); nft_auction_dispatcher.buy(nft_id_1); - // Forward block timestamp in order for a reduced nft price + // Forward block timestamp in order for a reduced nft price let forward_blocktime_by = 4000; // 4 seconds (in milliseconds) cheat_block_timestamp(nft_auction_address, forward_blocktime_by, CheatSpan::TargetCalls(1)); @@ -321,7 +322,7 @@ mod tests { nft_auction_dispatcher.buy(nft_id_1); // Forward block timestamp to a time after duration has ended - // During deployment, duration was set to 60 seconds + // During deployment, duration was set to 60 seconds let forward_blocktime_by = 61000; // 61 seconds (in milliseconds) cheat_block_timestamp(nft_auction_address, forward_blocktime_by, CheatSpan::TargetCalls(1)); diff --git a/listings/applications/simple_storage_starknetjs/Scarb.toml b/listings/applications/simple_storage_starknetjs/Scarb.toml index f22b7903..56c2d211 100644 --- a/listings/applications/simple_storage_starknetjs/Scarb.toml +++ b/listings/applications/simple_storage_starknetjs/Scarb.toml @@ -1,13 +1,16 @@ [package] name = "simple_storage" version.workspace = true -edition = "2023_11" +edition = "2024_07" [lib] [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/applications/simple_storage_starknetjs/src/storage.cairo b/listings/applications/simple_storage_starknetjs/src/storage.cairo index 38349241..b9f8805a 100644 --- a/listings/applications/simple_storage_starknetjs/src/storage.cairo +++ b/listings/applications/simple_storage_starknetjs/src/storage.cairo @@ -7,6 +7,8 @@ trait ISimpleStorage { #[starknet::contract] mod SimpleStorage { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + #[storage] struct Storage { stored_data: u128 diff --git a/listings/applications/simple_vault/Scarb.toml b/listings/applications/simple_vault/Scarb.toml index 561214d3..11d2642c 100644 --- a/listings/applications/simple_vault/Scarb.toml +++ b/listings/applications/simple_vault/Scarb.toml @@ -1,12 +1,15 @@ [package] name = "simple_vault" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true erc20 = { path = "../erc20" } +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/applications/simple_vault/src/lib.cairo b/listings/applications/simple_vault/src/lib.cairo index b5492840..b08098a0 100644 --- a/listings/applications/simple_vault/src/lib.cairo +++ b/listings/applications/simple_vault/src/lib.cairo @@ -1,5 +1,4 @@ mod simple_vault; - #[cfg(test)] mod tests; diff --git a/listings/applications/simple_vault/src/simple_vault.cairo b/listings/applications/simple_vault/src/simple_vault.cairo index 48b89d97..7251dce8 100644 --- a/listings/applications/simple_vault/src/simple_vault.cairo +++ b/listings/applications/simple_vault/src/simple_vault.cairo @@ -39,12 +39,16 @@ pub trait ISimpleVault { pub mod SimpleVault { use super::{IERC20Dispatcher, IERC20DispatcherTrait}; use starknet::{ContractAddress, get_caller_address, get_contract_address}; + use starknet::storage::{ + Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, + StoragePointerWriteAccess + }; #[storage] struct Storage { token: IERC20Dispatcher, total_supply: u256, - balance_of: LegacyMap + balance_of: Map } #[constructor] @@ -81,7 +85,7 @@ pub mod SimpleVault { // T = total supply // s = shares to mint // - // (T + s) / T = (a + B) / B + // (T + s) / T = (a + B) / B // // s = aT / B let caller = get_caller_address(); @@ -107,7 +111,7 @@ pub mod SimpleVault { // T = total supply // s = shares to burn // - // (T - s) / T = (B - a) / B + // (T - s) / T = (B - a) / B // // a = sB / T let caller = get_caller_address(); @@ -125,19 +129,14 @@ pub mod SimpleVault { #[cfg(test)] mod tests { - use super::{ - SimpleVault, ISimpleVaultDispatcher, ISimpleVaultDispatcherTrait, IERC20Dispatcher, - IERC20DispatcherTrait - }; + use super::{SimpleVault, ISimpleVaultDispatcher, ISimpleVaultDispatcherTrait,}; use erc20::token::{ IERC20DispatcherTrait as IERC20DispatcherTrait_token, IERC20Dispatcher as IERC20Dispatcher_token }; - use core::num::traits::Zero; use starknet::testing::{set_contract_address, set_account_contract_address}; use starknet::{ - ContractAddress, SyscallResultTrait, syscalls::deploy_syscall, get_caller_address, - contract_address_const + ContractAddress, SyscallResultTrait, syscalls::deploy_syscall, contract_address_const }; const token_name: felt252 = 'myToken'; diff --git a/listings/applications/staking/Scarb.toml b/listings/applications/staking/Scarb.toml index 7ac644c6..93510593 100644 --- a/listings/applications/staking/Scarb.toml +++ b/listings/applications/staking/Scarb.toml @@ -1,12 +1,15 @@ [package] name = "staking" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true openzeppelin.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/applications/staking/src/contract.cairo b/listings/applications/staking/src/contract.cairo index 21134ca0..5980b2c0 100644 --- a/listings/applications/staking/src/contract.cairo +++ b/listings/applications/staking/src/contract.cairo @@ -26,25 +26,29 @@ pub mod StakingContract { use core::num::traits::Zero; use starknet::{ContractAddress, get_caller_address, get_block_timestamp, get_contract_address}; use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait}; + use starknet::storage::{ + Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess, + StoragePointerWriteAccess + }; #[storage] struct Storage { - staking_token: IERC20Dispatcher, - reward_token: IERC20Dispatcher, - owner: ContractAddress, - reward_rate: u256, - duration: u256, - current_reward_per_staked_token: u256, - finish_at: u256, + pub staking_token: IERC20Dispatcher, + pub reward_token: IERC20Dispatcher, + pub owner: ContractAddress, + pub reward_rate: u256, + pub duration: u256, + pub current_reward_per_staked_token: u256, + pub finish_at: u256, // last time an operation (staking / withdrawal / rewards claimed) was registered - last_updated_at: u256, - last_user_reward_per_staked_token: LegacyMap::, - unclaimed_rewards: LegacyMap::, - total_distributed_rewards: u256, + pub last_updated_at: u256, + pub last_user_reward_per_staked_token: Map::, + pub unclaimed_rewards: Map::, + pub total_distributed_rewards: u256, // total amount of staked tokens - total_supply: u256, + pub total_supply: u256, // amount of staked tokens per user - balance_of: LegacyMap::, + pub balance_of: Map::, } #[event] @@ -125,7 +129,8 @@ pub mod StakingContract { self.reward_rate.write(rate); - // even if the previous reward duration has not finished, we reset the finish_at variable + // even if the previous reward duration has not finished, we reset the finish_at + // variable self.finish_at.write(block_timestamp + self.duration.read()); self.last_updated_at.write(block_timestamp); @@ -223,7 +228,8 @@ pub mod StakingContract { // owner should set up NEW rewards into the contract self.emit(RewardsFinished { msg: 'Rewards all distributed' }); } else { - // owner should set up rewards into the contract (or add duration by setting up rewards) + // owner should set up rewards into the contract (or add duration by setting up + // rewards) self.emit(RewardsFinished { msg: 'Rewards not active yet' }); } } @@ -248,7 +254,7 @@ pub mod StakingContract { #[inline(always)] fn last_time_applicable(self: @ContractState) -> u256 { - PrivateFunctions::min(self.finish_at.read(), get_block_timestamp().into()) + Self::min(self.finish_at.read(), get_block_timestamp().into()) } #[inline(always)] diff --git a/listings/applications/staking/src/tests/staking_tests.cairo b/listings/applications/staking/src/tests/staking_tests.cairo index 4e53031b..d899b876 100644 --- a/listings/applications/staking/src/tests/staking_tests.cairo +++ b/listings/applications/staking/src/tests/staking_tests.cairo @@ -1,27 +1,19 @@ mod tests { - use staking::contract::StakingContract::__member_module_unclaimed_rewards::InternalContractMemberStateTrait as UncRewInt; - use staking::contract::StakingContract::__member_module_last_updated_at::InternalContractMemberStateTrait as LastUpInt; - use staking::contract::StakingContract::__member_module_finish_at::InternalContractMemberStateTrait as FinInt; - use staking::contract::StakingContract::__member_module_reward_rate::InternalContractMemberStateTrait as RewRateInt; - use staking::contract::StakingContract::__member_module_total_supply::InternalContractMemberStateTrait as TotSupInt; - use staking::contract::StakingContract::__member_module_balance_of::InternalContractMemberStateTrait as BalInt; - use staking::contract::StakingContract::__member_module_staking_token::InternalContractMemberStateTrait as StakeTokInt; - use staking::contract::StakingContract::__member_module_reward_token::InternalContractMemberStateTrait as RewardTokInt; use openzeppelin::token::erc20::interface::IERC20DispatcherTrait; use openzeppelin::token::erc20::erc20::ERC20Component::InternalTrait; use staking::contract::IStakingContractDispatcherTrait; use staking::tests::tokens::{RewardToken, StakingToken}; use staking::contract::{ - StakingContract, IStakingContractDispatcher, StakingContract::ownerContractMemberStateTrait, - StakingContract::Event, StakingContract::Deposit, StakingContract::Withdrawal, - StakingContract::RewardsFinished + StakingContract, IStakingContractDispatcher, StakingContract::Event, + StakingContract::Deposit, StakingContract::Withdrawal, StakingContract::RewardsFinished }; use openzeppelin::token::erc20::{interface::IERC20Dispatcher}; use starknet::syscalls::deploy_syscall; use starknet::SyscallResultTrait; use core::serde::Serde; - use starknet::testing::{set_caller_address, set_contract_address, set_block_timestamp, pop_log}; - use starknet::{contract_address_const, ContractAddress, get_contract_address}; + use starknet::testing::{set_contract_address, set_block_timestamp, pop_log}; + use starknet::{contract_address_const, ContractAddress}; + use starknet::storage::{StoragePointerReadAccess, StorageMapReadAccess}; #[derive(Copy, Drop)] struct Deployment { @@ -107,7 +99,6 @@ mod tests { } #[test] - #[available_gas(20000000)] fn should_deploy() { /// setup let owner = contract_address_const::<'owner'>(); @@ -118,24 +109,21 @@ mod tests { // "link" a new StakingContract struct to the deployed StakingContract contract // in order to access its internal state fields for assertions - let state = StakingContract::contract_state_for_testing(); + let state = @StakingContract::contract_state_for_testing(); // pretend as if we were in the deployed contract set_contract_address(deploy.contract.contract_address); /// then - assert(state.owner.read() == owner, 'wrong owner'); - assert( - state.staking_token.read().contract_address == deploy.staking_token.contract_address, - 'wrong staking token contract' + assert_eq!(state.owner.read(), owner); + assert_eq!( + state.staking_token.read().contract_address, deploy.staking_token.contract_address ); - assert( - state.reward_token.read().contract_address == deploy.reward_token.contract_address, - 'wrong reward token contract' + assert_eq!( + state.reward_token.read().contract_address, deploy.reward_token.contract_address ); } #[test] - #[available_gas(20000000)] fn stake_and_withdraw_succeed() { /// set up @@ -156,14 +144,11 @@ mod tests { /// then // so far the user has 60 tokens left and staked 40 tokens - let state = StakingContract::contract_state_for_testing(); + let state = @StakingContract::contract_state_for_testing(); set_contract_address(deploy.contract.contract_address); - assert(state.balance_of.read(user) == stake_amount, '1- wrong user staking balance'); - assert(state.total_supply.read() == stake_amount, '1- wrong total supply'); - assert( - deploy.staking_token.balance_of(user) == amount_tokens_minted - stake_amount, - '1- wrong staking token balance' - ); + assert_eq!(state.balance_of.read(user), stake_amount); + assert_eq!(state.total_supply.read(), stake_amount); + assert_eq!(deploy.staking_token.balance_of(user), amount_tokens_minted - stake_amount); // check 1st & 2nd event - when user stakes assert_eq!( @@ -182,20 +167,13 @@ mod tests { /// then // at the end the user has 80 tokens left and 20 tokens staked - let state = StakingContract::contract_state_for_testing(); + let state = @StakingContract::contract_state_for_testing(); set_contract_address(deploy.contract.contract_address); - assert( - state.balance_of.read(user) == stake_amount - withdrawal_amount, - '2- wrong user staking balance' - ); - assert( - state.total_supply.read() == stake_amount - withdrawal_amount, '2- wrong total supply' - ); - assert( - deploy.staking_token.balance_of(user) == amount_tokens_minted - - stake_amount - + withdrawal_amount, - '2- wrong staking token balance' + assert_eq!(state.balance_of.read(user), stake_amount - withdrawal_amount); + assert_eq!(state.total_supply.read(), stake_amount - withdrawal_amount); + assert_eq!( + deploy.staking_token.balance_of(user), + amount_tokens_minted - stake_amount + withdrawal_amount ); // check 3rd & 4th events - when user withdraws @@ -210,7 +188,6 @@ mod tests { } #[test] - #[available_gas(20000000)] fn claim_rewards_3_users_scenario() { /// set up @@ -231,21 +208,18 @@ mod tests { let block_timestamp: u256 = 1000; set_block_timestamp(block_timestamp.try_into().unwrap()); let reward_duration = 100; - // have to set again the contract_address because it got changed in mint_reward_tokens_to function + // have to set again the contract_address because it got changed in mint_reward_tokens_to + // function set_contract_address(owner); deploy.contract.set_reward_duration(reward_duration); deploy.contract.set_reward_amount(reward_tokens_amount); // check reward rate, last updated at and finish dates - let state = StakingContract::contract_state_for_testing(); + let state = @StakingContract::contract_state_for_testing(); set_contract_address(deploy.contract.contract_address); - assert( - state.reward_rate.read() == reward_tokens_amount / reward_duration, 'Wrong reward rate' - ); - assert( - state.finish_at.read() == block_timestamp + reward_duration, 'Wrong reward finish date' - ); - assert(state.last_updated_at.read() == block_timestamp, 'Wrong reward last updated date'); + assert_eq!(state.reward_rate.read(), reward_tokens_amount / reward_duration); + assert_eq!(state.finish_at.read(), block_timestamp + reward_duration); + assert_eq!(state.last_updated_at.read(), block_timestamp); // mint staking tokens to alice let alice = contract_address_const::<'alice'>(); @@ -370,9 +344,11 @@ mod tests { // timestamp = 1110 // r6 = r5 + 10 * (1100 - 1090) / 10 = 15 + 10 = 25 // last updated at = 1100 (becomes same as finish_at) - // alice rewards = 600 + staked_tokens * (r6 - r5) = 600 + 0 * (25 - 15) = 600 -> 0 (claimed) + // alice rewards = 600 + staked_tokens * (r6 - r5) = 600 + 0 * (25 - 15) = 600 -> 0 + // (claimed) // bob rewards = 40 + staked_tokens * (r6 - r3) = 40 + 0 * (25 - 9) = 40 -> 0 (claimed) - // john rewards = 180 + staked_tokens * (r6 - r4) = 180 + 10 * (25 - 13) = 300 -> 0 (claimed) + // john rewards = 180 + staked_tokens * (r6 - r4) = 180 + 10 * (25 - 13) = 300 -> 0 + // (claimed) // last RPST for alice = r6 = 25 // last RPST for bob = r6 = 25 // last RPST for john = r6 = 25 @@ -380,7 +356,7 @@ mod tests { /// then - let state = StakingContract::contract_state_for_testing(); + let state = @StakingContract::contract_state_for_testing(); set_contract_address(deploy.contract.contract_address); // check amount of unclaimed reward tokens for each user @@ -400,27 +376,22 @@ mod tests { let deployed_contract_rewards = deploy .reward_token .balance_of(deploy.contract.contract_address); - assert(alice_rewards == 600, 'Alice: wrong amount of rewards'); - assert(bob_rewards == 40, 'Bob: wrong amount of rewards'); - assert(john_rewards == 300, 'John: wrong amount of rewards'); + assert_eq!(alice_rewards, 600); + assert_eq!(bob_rewards, 40); + assert_eq!(john_rewards, 300); // 1000 - 600 - 40 - 300 = 60 - assert(deployed_contract_rewards == 60, 'Contract: wrong rewards'); + assert_eq!(deployed_contract_rewards, 60); // check amount of staking tokens each user has back in their balance let alice_staking_tokens = deploy.staking_token.balance_of(alice); let bob_staking_tokens = deploy.staking_token.balance_of(bob); let john_staking_tokens = deploy.staking_token.balance_of(john); - assert( - alice_staking_tokens == alice_amount_tokens_minted, 'Alice: wrong amount of staking' - ); - assert(bob_staking_tokens == bob_amount_tokens_minted, 'Bob: wrong amount of staking'); - assert( - john_staking_tokens == john_amount_tokens_minted - 10, 'John: wrong amount of staking' - ); + assert_eq!(alice_staking_tokens, alice_amount_tokens_minted); + assert_eq!(bob_staking_tokens, bob_amount_tokens_minted); + assert_eq!(john_staking_tokens, john_amount_tokens_minted - 10); } #[test] - #[available_gas(20000000)] fn all_rewards_distributed_event() { /// set up @@ -441,7 +412,8 @@ mod tests { let block_timestamp: u256 = 1000; set_block_timestamp(block_timestamp.try_into().unwrap()); let reward_duration = 100; - // have to set again the contract_address because it got changed in mint_reward_tokens_to function + // have to set again the contract_address because it got changed in mint_reward_tokens_to + // function set_contract_address(owner); deploy.contract.set_reward_duration(reward_duration); deploy.contract.set_reward_amount(reward_tokens_amount); @@ -496,7 +468,6 @@ mod tests { } #[test] - #[available_gas(20000000)] fn set_up_reward_complex() { /// Set up @@ -518,22 +489,23 @@ mod tests { set_block_timestamp(block_timestamp.try_into().unwrap()); let reward_duration = 100; let initial_reward = 400; - // have to set again the contract_address because it got changed in mint_reward_tokens_to function + // have to set again the contract_address because it got changed in mint_reward_tokens_to + // function set_contract_address(owner); deploy.contract.set_reward_duration(reward_duration); deploy.contract.set_reward_amount(initial_reward); // middle check - let state = StakingContract::contract_state_for_testing(); + let state = @StakingContract::contract_state_for_testing(); set_contract_address(deploy.contract.contract_address); // timestamp = 1000 // finish_at = 1100 // reward_rate = 400 / 100 = 4 tokens/timestamp_unit - assert(state.finish_at.read() == block_timestamp + reward_duration, '1- Wrong finish date'); - assert(state.last_updated_at.read() == block_timestamp, '1- Wrong last update date'); - assert(state.reward_rate.read() == 4, '1- Wrong reward rate'); + assert_eq!(state.finish_at.read(), block_timestamp + reward_duration); + assert_eq!(state.last_updated_at.read(), block_timestamp); + assert_eq!(state.reward_rate.read(), 4); /// When @@ -553,14 +525,12 @@ mod tests { // new_reward_rate = (200 + 300) / 100 = 5 // new_finish_at = 1050 + 100 = 1150 - let state = StakingContract::contract_state_for_testing(); + let state = @StakingContract::contract_state_for_testing(); set_contract_address(deploy.contract.contract_address); // the finish_at date is reset - assert( - state.finish_at.read() == middle_timestamp + reward_duration, '2- Wrong finish date' - ); - assert(state.last_updated_at.read() == middle_timestamp, '2- Wrong last update date'); - assert(state.reward_rate.read() == 5, ''); + assert_eq!(state.finish_at.read(), middle_timestamp + reward_duration); + assert_eq!(state.last_updated_at.read(), middle_timestamp); + assert_eq!(state.reward_rate.read(), 5); } } diff --git a/listings/applications/staking/src/tests/tokens.cairo b/listings/applications/staking/src/tests/tokens.cairo index ea788565..0b0148c6 100644 --- a/listings/applications/staking/src/tests/tokens.cairo +++ b/listings/applications/staking/src/tests/tokens.cairo @@ -12,7 +12,7 @@ pub mod RewardToken { #[storage] struct Storage { #[substorage(v0)] - erc20: ERC20Component::Storage, + pub erc20: ERC20Component::Storage, } #[event] @@ -49,7 +49,7 @@ pub mod StakingToken { #[storage] struct Storage { #[substorage(v0)] - erc20: ERC20Component::Storage, + pub erc20: ERC20Component::Storage, } #[event] diff --git a/listings/applications/timelock/Scarb.toml b/listings/applications/timelock/Scarb.toml index a3eaafbf..eed924b6 100644 --- a/listings/applications/timelock/Scarb.toml +++ b/listings/applications/timelock/Scarb.toml @@ -1,17 +1,17 @@ [package] name = "timelock" version.workspace = true -edition = "2023_11" +edition = "2024_07" [dependencies] starknet.workspace = true -# Starknet Foundry: snforge_std.workspace = true -# OpenZeppelin: openzeppelin.workspace = true -# StarknetByExample Components components.workspace = true +[dev-dependencies] +assert_macros.workspace = true + [scripts] test.workspace = true diff --git a/listings/applications/timelock/src/tests/timelock.cairo b/listings/applications/timelock/src/tests/timelock.cairo index f3e6c871..dd0c98da 100644 --- a/listings/applications/timelock/src/tests/timelock.cairo +++ b/listings/applications/timelock/src/tests/timelock.cairo @@ -1,11 +1,9 @@ use core::panic_with_felt252; -use starknet::get_block_timestamp; use starknet::account::Call; use core::poseidon::{PoseidonTrait, poseidon_hash_span}; -use core::hash::{HashStateTrait, HashStateExTrait}; +use core::hash::HashStateTrait; use snforge_std::{ - cheat_caller_address, cheat_block_timestamp, CheatSpan, spy_events, SpyOn, EventSpy, - EventAssertions + cheat_caller_address, cheat_block_timestamp, CheatSpan, spy_events, EventSpyAssertionsTrait }; use openzeppelin::token::erc721::interface::IERC721DispatcherTrait; use openzeppelin::token::erc721::erc721::ERC721Component; @@ -75,7 +73,7 @@ fn test_queue_timestamp_not_in_range() { #[test] fn test_queue_success() { let timelock_test = TimeLockTestTrait::setup(); - let mut spy = spy_events(SpyOn::One(timelock_test.timelock_address)); + let mut spy = spy_events(); let timestamp = timelock_test.get_timestamp(); let tx_id = timelock_test.timelock.queue(timelock_test.get_call(), timestamp); spy @@ -154,7 +152,7 @@ fn test_execute_success() { timelock_test.timelock.queue(timelock_test.get_call(), timestamp); timelock_test.erc721.approve(timelock_test.timelock_address, TOKEN_ID); cheat_block_timestamp(timelock_test.timelock_address, timestamp + 1, CheatSpan::TargetCalls(1)); - let mut spy = spy_events(SpyOn::One(timelock_test.timelock_address)); + let mut spy = spy_events(); timelock_test.timelock.execute(timelock_test.get_call(), timestamp); spy .assert_emitted( @@ -214,7 +212,7 @@ fn test_cancel_success() { let tx_id = timelock_test .timelock .queue(timelock_test.get_call(), timelock_test.get_timestamp()); - let mut spy = spy_events(SpyOn::One(timelock_test.timelock_address)); + let mut spy = spy_events(); timelock_test.timelock.cancel(tx_id); spy .assert_emitted( diff --git a/listings/applications/timelock/src/tests/utils.cairo b/listings/applications/timelock/src/tests/utils.cairo index c8de72a5..32973908 100644 --- a/listings/applications/timelock/src/tests/utils.cairo +++ b/listings/applications/timelock/src/tests/utils.cairo @@ -1,6 +1,6 @@ use starknet::{ContractAddress, contract_address_const, get_block_timestamp}; use starknet::account::Call; -use snforge_std::{declare, ContractClassTrait, test_address}; +use snforge_std::{declare, ContractClassTrait, test_address, DeclareResultTrait}; use openzeppelin::utils::serde::SerializedAppend; use openzeppelin::token::erc721::interface::IERC721Dispatcher; use timelock::timelock::{TimeLock, ITimeLockDispatcher, ITimeLockSafeDispatcher}; @@ -35,12 +35,12 @@ pub struct TimeLockTest { #[generate_trait] pub impl TimeLockTestImpl of TimeLockTestTrait { fn setup() -> TimeLockTest { - let timelock_contract = declare("TimeLock").unwrap(); + let timelock_contract = *declare("TimeLock").unwrap().contract_class(); let mut timelock_calldata = array![]; let (timelock_address, _) = timelock_contract.deploy(@timelock_calldata).unwrap(); let timelock = ITimeLockDispatcher { contract_address: timelock_address }; let timelock_safe = ITimeLockSafeDispatcher { contract_address: timelock_address }; - let erc721_contract = declare("ERC721").unwrap(); + let erc721_contract = *declare("ERC721").unwrap().contract_class(); let mut erc721_calldata = array![]; erc721_calldata.append_serde(NAME()); erc721_calldata.append_serde(SYMBOL()); diff --git a/listings/applications/timelock/src/timelock.cairo b/listings/applications/timelock/src/timelock.cairo index 29081790..38e42ed9 100644 --- a/listings/applications/timelock/src/timelock.cairo +++ b/listings/applications/timelock/src/timelock.cairo @@ -1,4 +1,3 @@ -use starknet::ContractAddress; use starknet::account::Call; #[starknet::interface] @@ -12,12 +11,11 @@ pub trait ITimeLock { #[starknet::contract] pub mod TimeLock { use core::poseidon::{PoseidonTrait, poseidon_hash_span}; - use core::hash::{HashStateTrait, HashStateExTrait}; - use starknet::{ - ContractAddress, get_caller_address, get_block_timestamp, SyscallResultTrait, syscalls - }; + use core::hash::HashStateTrait; + use starknet::{get_caller_address, get_block_timestamp, SyscallResultTrait, syscalls}; use starknet::account::Call; use components::ownable::ownable_component; + use starknet::storage::{Map, StorageMapReadAccess, StorageMapWriteAccess}; component!(path: ownable_component, storage: ownable, event: OwnableEvent); @@ -30,7 +28,7 @@ pub mod TimeLock { struct Storage { #[substorage(v0)] ownable: ownable_component::Storage, - queued: LegacyMap::, + queued: Map::, } #[event] diff --git a/listings/applications/upgradeable_contract/Scarb.toml b/listings/applications/upgradeable_contract/Scarb.toml index 8256c5fa..c4dcec0d 100644 --- a/listings/applications/upgradeable_contract/Scarb.toml +++ b/listings/applications/upgradeable_contract/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "upgradeable_contract" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/applications/upgradeable_contract/src/tests.cairo b/listings/applications/upgradeable_contract/src/tests.cairo index 3c3e7ee2..a60886a6 100644 --- a/listings/applications/upgradeable_contract/src/tests.cairo +++ b/listings/applications/upgradeable_contract/src/tests.cairo @@ -34,7 +34,7 @@ mod tests { ) } - // deploy v1 contract + // deploy v1 contract fn deploy_v1() -> (IUpgradeableContractDispatcher_v1, ContractAddress, ClassHash) { let (contract_address, _) = deploy_syscall( UpgradeableContract_V1::TEST_CLASS_HASH.try_into().unwrap(), 0, array![].span(), false diff --git a/listings/getting-started/bytearray/Scarb.toml b/listings/getting-started/bytearray/Scarb.toml index 5b76d327..21e61cdd 100644 --- a/listings/getting-started/bytearray/Scarb.toml +++ b/listings/getting-started/bytearray/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "bytearray" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/bytearray/src/bytearray.cairo b/listings/getting-started/bytearray/src/bytearray.cairo index 43793bd1..52d8de06 100644 --- a/listings/getting-started/bytearray/src/bytearray.cairo +++ b/listings/getting-started/bytearray/src/bytearray.cairo @@ -7,9 +7,11 @@ pub trait IMessage { // ANCHOR: contract #[starknet::contract] pub mod MessageContract { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + #[storage] struct Storage { - message: ByteArray + pub message: ByteArray } #[constructor] @@ -32,9 +34,8 @@ pub mod MessageContract { #[cfg(test)] mod tests { - use bytearray::bytearray::{ - MessageContract::messageContractMemberStateTrait, MessageContract, IMessage - }; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + use bytearray::bytearray::{MessageContract, IMessage}; #[test] #[available_gas(2000000000)] diff --git a/listings/getting-started/cairo_cheatsheet/Scarb.toml b/listings/getting-started/cairo_cheatsheet/Scarb.toml index 138959f1..b1ec0393 100644 --- a/listings/getting-started/cairo_cheatsheet/Scarb.toml +++ b/listings/getting-started/cairo_cheatsheet/Scarb.toml @@ -1,12 +1,16 @@ [package] name = "cairo_cheatsheet" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true [[target.starknet-contract]] +allowed-libfuncs-list.name = "experimental" diff --git a/listings/getting-started/cairo_cheatsheet/src/dict_example.cairo b/listings/getting-started/cairo_cheatsheet/src/dict_example.cairo index 13a70676..6cbd748d 100644 --- a/listings/getting-started/cairo_cheatsheet/src/dict_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/dict_example.cairo @@ -1,4 +1,6 @@ // ANCHOR: sheet +use core::dict::Felt252Dict; + fn dict() { let mut Auctions: Felt252Dict = Default::default(); diff --git a/listings/getting-started/cairo_cheatsheet/src/enum_example.cairo b/listings/getting-started/cairo_cheatsheet/src/enum_example.cairo index 8364485c..8695bb38 100644 --- a/listings/getting-started/cairo_cheatsheet/src/enum_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/enum_example.cairo @@ -31,7 +31,7 @@ trait IEnumContract { #[starknet::contract] mod EnumContract { - use core::clone::Clone; + use starknet::storage::StoragePointerWriteAccess; use super::IEnumContract; use super::{Action, Position, UserCommand}; diff --git a/listings/getting-started/cairo_cheatsheet/src/felt_example.cairo b/listings/getting-started/cairo_cheatsheet/src/felt_example.cairo index d556fd8c..43ab4360 100644 --- a/listings/getting-started/cairo_cheatsheet/src/felt_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/felt_example.cairo @@ -4,5 +4,5 @@ fn felt() { let felt_as_str = 'Hello Starknet!'; let _felt = felt + felt_as_str; -// ANCHOR_END: sheet + // ANCHOR_END: sheet } diff --git a/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo b/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo index 5abd9885..65860332 100644 --- a/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo @@ -14,5 +14,5 @@ fn do_loop() { i += 1; }; -// ANCHOR_END: sheet + // ANCHOR_END: sheet } diff --git a/listings/getting-started/cairo_cheatsheet/src/mapping_example.cairo b/listings/getting-started/cairo_cheatsheet/src/mapping_example.cairo index bd107b91..176a2240 100644 --- a/listings/getting-started/cairo_cheatsheet/src/mapping_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/mapping_example.cairo @@ -15,11 +15,12 @@ trait IMappingExample { #[starknet::contract] mod MappingContract { use starknet::ContractAddress; + use starknet::storage::{Map, StorageMapReadAccess, StorageMapWriteAccess}; #[storage] struct Storage { - students_name: LegacyMap::, - students_result_record: LegacyMap::<(ContractAddress, felt252), u16>, + students_name: Map::, + students_result_record: Map::<(ContractAddress, felt252), u16>, } #[abi(embed_v0)] diff --git a/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo b/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo index dab039b0..4f54e255 100644 --- a/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo @@ -9,5 +9,5 @@ fn tuple() { // Access tuple let (address, age, active) = stored_tuple; -// ANCHOR_END: sheet + // ANCHOR_END: sheet } diff --git a/listings/getting-started/cairo_cheatsheet/src/type_casting_example.cairo b/listings/getting-started/cairo_cheatsheet/src/type_casting_example.cairo index 17150e32..9e2bbfea 100644 --- a/listings/getting-started/cairo_cheatsheet/src/type_casting_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/type_casting_example.cairo @@ -23,5 +23,5 @@ fn type_casting() { // Note: usize is smaller than felt252, so we use try_into let _new_usize: usize = my_felt252.try_into().unwrap(); -// ANCHOR_END: sheet + // ANCHOR_END: sheet } diff --git a/listings/getting-started/cairo_cheatsheet/src/while_example.cairo b/listings/getting-started/cairo_cheatsheet/src/while_example.cairo index c9011114..c681ac2c 100644 --- a/listings/getting-started/cairo_cheatsheet/src/while_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/while_example.cairo @@ -7,5 +7,5 @@ fn do_loop() { arr.append(i); i += 1; }; -// ANCHOR_END: sheet + // ANCHOR_END: sheet } diff --git a/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo b/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo index edc475e0..6e3035af 100644 --- a/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo @@ -4,15 +4,14 @@ fn while_let() { // "while `let` destructures `option` into `Some(i)`, // evaluate the block (`{}`), else `break` - while let Option::Some(i) = - option { - if i > 0 { - println!("Greater than 0, break..."); - option = Option::None; - } else { - println!("`i` is `{:?}`. Try again.", i); - option = Option::Some(i + 1); - } + while let Option::Some(i) = option { + if i > 0 { + println!("Greater than 0, break..."); + option = Option::None; + } else { + println!("`i` is `{:?}`. Try again.", i); + option = Option::Some(i + 1); } -// ANCHOR_END: sheet + } + // ANCHOR_END: sheet } diff --git a/listings/getting-started/calling_other_contracts/Scarb.toml b/listings/getting-started/calling_other_contracts/Scarb.toml index 39c622eb..f1727dbd 100644 --- a/listings/getting-started/calling_other_contracts/Scarb.toml +++ b/listings/getting-started/calling_other_contracts/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "calling_other_contracts" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/calling_other_contracts/src/caller.cairo b/listings/getting-started/calling_other_contracts/src/caller.cairo index 35ac8381..b82ff2e3 100644 --- a/listings/getting-started/calling_other_contracts/src/caller.cairo +++ b/listings/getting-started/calling_other_contracts/src/caller.cairo @@ -7,9 +7,11 @@ pub trait ICallee { #[starknet::contract] pub mod Callee { + use starknet::storage::StoragePointerWriteAccess; + #[storage] struct Storage { - value: u128, + pub value: u128, } #[abi(embed_v0)] @@ -51,14 +53,9 @@ pub mod Caller { #[cfg(test)] mod tests { - use super::{ - Callee, ICalleeDispatcher, ICalleeDispatcherTrait, Callee::valueContractMemberStateTrait, - Caller, ICallerDispatcher, ICallerDispatcherTrait - }; - use starknet::{ - ContractAddress, contract_address_const, testing::set_contract_address, - syscalls::deploy_syscall, SyscallResultTrait - }; + use super::{Callee, ICalleeDispatcher, Caller, ICallerDispatcher, ICallerDispatcherTrait}; + use starknet::{testing::set_contract_address, syscalls::deploy_syscall, SyscallResultTrait}; + use starknet::storage::StoragePointerReadAccess; fn deploy() -> (ICalleeDispatcher, ICallerDispatcher) { let (address_callee, _) = deploy_syscall( @@ -82,7 +79,7 @@ mod tests { let (callee, caller) = deploy(); caller.set_value_from_address(callee.contract_address, init_value); - let state = Callee::contract_state_for_testing(); + let state = @Callee::contract_state_for_testing(); set_contract_address(callee.contract_address); let value_read: u128 = state.value.read(); diff --git a/listings/getting-started/constructor/Scarb.toml b/listings/getting-started/constructor/Scarb.toml index 20437aeb..8235973e 100644 --- a/listings/getting-started/constructor/Scarb.toml +++ b/listings/getting-started/constructor/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "constructor" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/constructor/src/constructor.cairo b/listings/getting-started/constructor/src/constructor.cairo index be30f961..bf68ac8d 100644 --- a/listings/getting-started/constructor/src/constructor.cairo +++ b/listings/getting-started/constructor/src/constructor.cairo @@ -2,10 +2,11 @@ #[starknet::contract] pub mod ExampleConstructor { use starknet::ContractAddress; + use starknet::storage::{Map, StorageMapWriteAccess}; #[storage] struct Storage { - names: LegacyMap::, + pub names: Map::, } // The constructor is decorated with a `#[constructor]` attribute. @@ -19,9 +20,10 @@ pub mod ExampleConstructor { #[cfg(test)] mod tests { - use super::{ExampleConstructor, ExampleConstructor::namesContractMemberStateTrait}; + use super::ExampleConstructor; use starknet::{ContractAddress, SyscallResultTrait, syscalls::deploy_syscall}; use starknet::{contract_address_const, testing::{set_contract_address}}; + use starknet::storage::StorageMapReadAccess; #[test] fn should_deploy_with_constructor_init_value() { @@ -36,7 +38,7 @@ mod tests { ) .unwrap_syscall(); - let state = ExampleConstructor::contract_state_for_testing(); + let state = @ExampleConstructor::contract_state_for_testing(); set_contract_address(contract_address); let name = state.names.read(address); diff --git a/listings/getting-started/counter/Scarb.toml b/listings/getting-started/counter/Scarb.toml index 64469a3a..1a78d653 100644 --- a/listings/getting-started/counter/Scarb.toml +++ b/listings/getting-started/counter/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "counter" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/counter/src/counter.cairo b/listings/getting-started/counter/src/counter.cairo index 0a719b8d..83d8e287 100644 --- a/listings/getting-started/counter/src/counter.cairo +++ b/listings/getting-started/counter/src/counter.cairo @@ -8,10 +8,12 @@ pub trait ISimpleCounter { // ANCHOR: contract #[starknet::contract] pub mod SimpleCounter { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + #[storage] struct Storage { // Counter variable - counter: u128, + pub counter: u128, } #[constructor] @@ -44,7 +46,7 @@ pub mod SimpleCounter { #[cfg(test)] mod test { use super::{SimpleCounter, ISimpleCounterDispatcher, ISimpleCounterDispatcherTrait}; - use starknet::{ContractAddress, SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; fn deploy(init_value: u128) -> ISimpleCounterDispatcher { let (contract_address, _) = deploy_syscall( diff --git a/listings/getting-started/custom_type_serde/Scarb.toml b/listings/getting-started/custom_type_serde/Scarb.toml index 74569a87..5414b1dd 100644 --- a/listings/getting-started/custom_type_serde/Scarb.toml +++ b/listings/getting-started/custom_type_serde/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "custom_type_serde" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/custom_type_serde/src/contract.cairo b/listings/getting-started/custom_type_serde/src/contract.cairo index 9a320b75..b70142cc 100644 --- a/listings/getting-started/custom_type_serde/src/contract.cairo +++ b/listings/getting-started/custom_type_serde/src/contract.cairo @@ -36,7 +36,7 @@ mod tests { use super::{ SerdeCustomType, Person, ISerdeCustomTypeDispatcher, ISerdeCustomTypeDispatcherTrait }; - use starknet::{ContractAddress, syscalls::deploy_syscall, SyscallResultTrait}; + use starknet::{syscalls::deploy_syscall, SyscallResultTrait}; fn deploy() -> ISerdeCustomTypeDispatcher { let (contract_address, _) = deploy_syscall( diff --git a/listings/getting-started/errors/Scarb.toml b/listings/getting-started/errors/Scarb.toml index 4f180125..2b8cc106 100644 --- a/listings/getting-started/errors/Scarb.toml +++ b/listings/getting-started/errors/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "errors" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/errors/src/custom_errors.cairo b/listings/getting-started/errors/src/custom_errors.cairo index eca2e00c..d7216f96 100644 --- a/listings/getting-started/errors/src/custom_errors.cairo +++ b/listings/getting-started/errors/src/custom_errors.cairo @@ -37,7 +37,7 @@ mod test { use super::{ CustomErrorsExample, ICustomErrorsExampleDispatcher, ICustomErrorsExampleDispatcherTrait }; - use starknet::{ContractAddress, SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; fn deploy() -> ICustomErrorsExampleDispatcher { let (contract_address, _) = deploy_syscall( diff --git a/listings/getting-started/errors/src/simple_errors.cairo b/listings/getting-started/errors/src/simple_errors.cairo index 28886b0a..d1d387cd 100644 --- a/listings/getting-started/errors/src/simple_errors.cairo +++ b/listings/getting-started/errors/src/simple_errors.cairo @@ -31,7 +31,7 @@ pub mod ErrorsExample { #[cfg(test)] mod test { use super::{ErrorsExample, IErrorsExampleDispatcher, IErrorsExampleDispatcherTrait}; - use starknet::{ContractAddress, SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; fn deploy() -> IErrorsExampleDispatcher { let (contract_address, _) = deploy_syscall( diff --git a/listings/getting-started/errors/src/vault_errors.cairo b/listings/getting-started/errors/src/vault_errors.cairo index 4f34b951..20c230c8 100644 --- a/listings/getting-started/errors/src/vault_errors.cairo +++ b/listings/getting-started/errors/src/vault_errors.cairo @@ -7,11 +7,12 @@ pub trait IVaultErrorsExample { // ANCHOR: contract pub mod VaultErrors { pub const INSUFFICIENT_BALANCE: felt252 = 'insufficient_balance'; -// you can define more errors here + // you can define more errors here } #[starknet::contract] pub mod VaultErrorsExample { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; use super::VaultErrors; #[storage] @@ -50,7 +51,7 @@ mod test { use super::{ VaultErrorsExample, IVaultErrorsExampleDispatcher, IVaultErrorsExampleDispatcherTrait }; - use starknet::{ContractAddress, SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; fn deploy() -> IVaultErrorsExampleDispatcher { let (contract_address, _) = deploy_syscall( diff --git a/listings/getting-started/events/Scarb.toml b/listings/getting-started/events/Scarb.toml index 7c248e1f..58d641fa 100644 --- a/listings/getting-started/events/Scarb.toml +++ b/listings/getting-started/events/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "events" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/events/src/counter.cairo b/listings/getting-started/events/src/counter.cairo index 10d879a6..8b71d774 100644 --- a/listings/getting-started/events/src/counter.cairo +++ b/listings/getting-started/events/src/counter.cairo @@ -7,11 +7,12 @@ pub trait IEventCounter { #[starknet::contract] pub mod EventCounter { use starknet::{get_caller_address, ContractAddress}; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; #[storage] struct Storage { // Counter value - counter: u128, + pub counter: u128, } #[event] @@ -54,7 +55,7 @@ pub mod EventCounter { } ) ); - // ANCHOR_END: emit + // ANCHOR_END: emit } } } @@ -63,16 +64,12 @@ pub mod EventCounter { #[cfg(test)] mod tests { use super::{ - EventCounter, - EventCounter::{ - counterContractMemberStateTrait, Event, CounterIncreased, UserIncreaseCounter - }, + EventCounter, EventCounter::{Event, CounterIncreased, UserIncreaseCounter}, IEventCounterDispatcherTrait, IEventCounterDispatcher }; - use starknet::{ - ContractAddress, contract_address_const, SyscallResultTrait, syscalls::deploy_syscall - }; - use starknet::testing::{set_contract_address, set_account_contract_address}; + use starknet::{contract_address_const, SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::testing::set_contract_address; + use starknet::storage::StoragePointerReadAccess; #[test] fn test_increment_events() { @@ -81,7 +78,7 @@ mod tests { ) .unwrap_syscall(); let mut contract = IEventCounterDispatcher { contract_address }; - let state = EventCounter::contract_state_for_testing(); + let state = @EventCounter::contract_state_for_testing(); let amount = 10; let caller = contract_address_const::<'caller'>(); diff --git a/listings/getting-started/factory/Scarb.toml b/listings/getting-started/factory/Scarb.toml index 23664f2c..5df9fd4c 100644 --- a/listings/getting-started/factory/Scarb.toml +++ b/listings/getting-started/factory/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "factory" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/factory/src/simple_factory.cairo b/listings/getting-started/factory/src/simple_factory.cairo index 83e6f22f..6b6452d7 100644 --- a/listings/getting-started/factory/src/simple_factory.cairo +++ b/listings/getting-started/factory/src/simple_factory.cairo @@ -19,6 +19,7 @@ pub trait ICounterFactory { #[starknet::contract] pub mod CounterFactory { use starknet::{ContractAddress, ClassHash, SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; #[storage] struct Storage { @@ -69,10 +70,7 @@ pub mod CounterFactory { #[cfg(test)] mod tests { use super::{CounterFactory, ICounterFactoryDispatcher, ICounterFactoryDispatcherTrait}; - use starknet::{ - SyscallResultTrait, ContractAddress, ClassHash, contract_address_const, - syscalls::deploy_syscall - }; + use starknet::{SyscallResultTrait, ClassHash, syscalls::deploy_syscall}; // Define a target contract to deploy mod target { @@ -85,6 +83,8 @@ mod tests { #[starknet::contract] pub mod SimpleCounter { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + #[storage] struct Storage { // Counter variable @@ -116,7 +116,7 @@ mod tests { } } } - use target::{ISimpleCounterDispatcher, ISimpleCounterDispatcherTrait}; + use target::ISimpleCounterDispatcherTrait; /// Deploy a counter factory contract fn deploy_factory( diff --git a/listings/getting-started/interfaces_traits/Scarb.toml b/listings/getting-started/interfaces_traits/Scarb.toml index 4aa5e26d..94a47b46 100644 --- a/listings/getting-started/interfaces_traits/Scarb.toml +++ b/listings/getting-started/interfaces_traits/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "interfaces_traits" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/interfaces_traits/src/explicit.cairo b/listings/getting-started/interfaces_traits/src/explicit.cairo index d31bd219..0c9b109e 100644 --- a/listings/getting-started/interfaces_traits/src/explicit.cairo +++ b/listings/getting-started/interfaces_traits/src/explicit.cairo @@ -7,6 +7,8 @@ pub trait IExplicitInterfaceContract { #[starknet::contract] pub mod ExplicitInterfaceContract { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + #[storage] struct Storage { value: u32 @@ -28,10 +30,10 @@ pub mod ExplicitInterfaceContract { #[cfg(test)] mod tests { use super::{ - IExplicitInterfaceContract, ExplicitInterfaceContract, IExplicitInterfaceContractDispatcher, + ExplicitInterfaceContract, IExplicitInterfaceContractDispatcher, IExplicitInterfaceContractDispatcherTrait }; - use starknet::{ContractAddress, SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; #[test] fn test_interface() { diff --git a/listings/getting-started/interfaces_traits/src/implicit.cairo b/listings/getting-started/interfaces_traits/src/implicit.cairo index 47e8e5f3..15861ba5 100644 --- a/listings/getting-started/interfaces_traits/src/implicit.cairo +++ b/listings/getting-started/interfaces_traits/src/implicit.cairo @@ -1,6 +1,8 @@ // ANCHOR: contract #[starknet::contract] pub mod ImplicitInterfaceContract { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + #[storage] struct Storage { value: u32 @@ -24,13 +26,8 @@ pub mod ImplicitInterfaceContract { #[cfg(test)] mod tests { - use super::{ - ImplicitInterfaceContract, ImplicitInterfaceContract::valueContractMemberStateTrait, - ImplicitInterfaceContract::IImplicitInterfaceContract - }; - use starknet::{ - ContractAddress, SyscallResultTrait, syscalls::deploy_syscall, testing::set_contract_address - }; + use super::{ImplicitInterfaceContract, ImplicitInterfaceContract::IImplicitInterfaceContract}; + use starknet::{SyscallResultTrait, syscalls::deploy_syscall, testing::set_contract_address}; #[test] fn test_interface() { diff --git a/listings/getting-started/interfaces_traits/src/implicit_internal.cairo b/listings/getting-started/interfaces_traits/src/implicit_internal.cairo index a10cf8f6..2dc83f15 100644 --- a/listings/getting-started/interfaces_traits/src/implicit_internal.cairo +++ b/listings/getting-started/interfaces_traits/src/implicit_internal.cairo @@ -8,6 +8,8 @@ pub trait IImplicitInternalContract { #[starknet::contract] pub mod ImplicitInternalContract { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + #[storage] struct Storage { value: u32 @@ -49,10 +51,10 @@ pub mod ImplicitInternalContract { #[cfg(test)] mod tests { use super::{ - IImplicitInternalContract, ImplicitInternalContract, IImplicitInternalContractDispatcher, + ImplicitInternalContract, IImplicitInternalContractDispatcher, IImplicitInternalContractDispatcherTrait }; - use starknet::{ContractAddress, SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; #[test] fn test_interface() { diff --git a/listings/getting-started/mappings/Scarb.toml b/listings/getting-started/mappings/Scarb.toml index 796fdbc2..a1f50323 100644 --- a/listings/getting-started/mappings/Scarb.toml +++ b/listings/getting-started/mappings/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "mappings" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test = "2.7.1" + [scripts] test.workspace = true diff --git a/listings/getting-started/mappings/src/mappings.cairo b/listings/getting-started/mappings/src/mappings.cairo index 5fd4423e..802152cc 100644 --- a/listings/getting-started/mappings/src/mappings.cairo +++ b/listings/getting-started/mappings/src/mappings.cairo @@ -10,11 +10,11 @@ pub trait IMapContract { #[starknet::contract] pub mod MapContract { use starknet::ContractAddress; + use starknet::storage::{Map, StorageMapReadAccess, StorageMapWriteAccess}; #[storage] struct Storage { - // The `LegacyMap` type is only available inside the `Storage` struct. - map: LegacyMap::, + map: Map::, } #[abi(embed_v0)] @@ -33,7 +33,7 @@ pub mod MapContract { #[cfg(test)] mod test { use super::{MapContract, IMapContractDispatcher, IMapContractDispatcherTrait}; - use starknet::{ContractAddress, SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; #[test] fn test_deploy_and_set_get() { diff --git a/listings/getting-started/storage/Scarb.toml b/listings/getting-started/storage/Scarb.toml index e912d31b..caf77195 100644 --- a/listings/getting-started/storage/Scarb.toml +++ b/listings/getting-started/storage/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "storage" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/storage/src/contract.cairo b/listings/getting-started/storage/src/contract.cairo index 44ec565c..75d734a5 100644 --- a/listings/getting-started/storage/src/contract.cairo +++ b/listings/getting-started/storage/src/contract.cairo @@ -3,9 +3,9 @@ pub mod Contract { #[storage] struct Storage { - a: u128, - b: u8, - c: u256 + pub a: u128, + pub b: u8, + pub c: u256 } } // ANCHOR_END: contract @@ -14,9 +14,7 @@ pub mod Contract { mod test { use super::Contract; use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; - use storage::contract::Contract::{ - aContractMemberStateTrait, bContractMemberStateTrait, cContractMemberStateTrait - }; + use starknet::storage::StoragePointerReadAccess; #[test] fn test_can_deploy() { @@ -28,7 +26,7 @@ mod test { #[test] fn test_storage_members() { - let state = Contract::contract_state_for_testing(); + let state = @Contract::contract_state_for_testing(); assert_eq!(state.a.read(), 0_u128); assert_eq!(state.b.read(), 0_u8); assert_eq!(state.c.read(), 0_u256); diff --git a/listings/getting-started/storage/src/minimal_contract.cairo b/listings/getting-started/storage/src/minimal_contract.cairo index 28128fc7..22bb7ccc 100644 --- a/listings/getting-started/storage/src/minimal_contract.cairo +++ b/listings/getting-started/storage/src/minimal_contract.cairo @@ -17,7 +17,7 @@ mod test { Contract::TEST_CLASS_HASH.try_into().unwrap(), 0, array![].span(), false ) .unwrap_syscall(); - // Not much to test + // Not much to test } } diff --git a/listings/getting-started/storing_custom_types/Scarb.toml b/listings/getting-started/storing_custom_types/Scarb.toml index f41505d2..4a949d4f 100644 --- a/listings/getting-started/storing_custom_types/Scarb.toml +++ b/listings/getting-started/storing_custom_types/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "storing_custom_types" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/storing_custom_types/src/contract.cairo b/listings/getting-started/storing_custom_types/src/contract.cairo index f3c80c98..f786a9be 100644 --- a/listings/getting-started/storing_custom_types/src/contract.cairo +++ b/listings/getting-started/storing_custom_types/src/contract.cairo @@ -1,6 +1,7 @@ #[starknet::interface] pub trait IStoringCustomType { fn set_person(ref self: TContractState, person: Person); + fn set_name(ref self: TContractState, name: felt252); } // ANCHOR: contract @@ -14,10 +15,11 @@ pub struct Person { #[starknet::contract] pub mod StoringCustomType { + use starknet::storage::StoragePointerWriteAccess; use super::Person; #[storage] - pub struct Storage { + struct Storage { pub person: Person } @@ -26,16 +28,20 @@ pub mod StoringCustomType { fn set_person(ref self: ContractState, person: Person) { self.person.write(person); } + + // ANCHOR: set_name + fn set_name(ref self: ContractState, name: felt252) { + self.person.name.write(name); + } + // ANCHOR_END: set_name } } // ANCHOR_END: contract #[cfg(test)] mod tests { - use super::{ - IStoringCustomType, StoringCustomType, Person, - StoringCustomType::personContractMemberStateTrait - }; + use super::{IStoringCustomType, StoringCustomType, Person,}; + use starknet::storage::StoragePointerReadAccess; #[test] fn can_call_set_person() { @@ -44,9 +50,20 @@ mod tests { let person = Person { age: 10, name: 'Joe' }; state.set_person(person); + let read_person = state.person.read(); - assert(person.age == read_person.age, 'wrong age'); - assert(person.name == read_person.name, 'wrong name'); + assert_eq!(person.age, read_person.age); + assert_eq!(person.name, read_person.name); + } + + #[test] + fn can_call_set_name() { + let mut state = StoringCustomType::contract_state_for_testing(); + + state.set_name('John'); + + let read_person = state.person.read(); + assert_eq!(read_person.name, 'John'); } } diff --git a/listings/getting-started/testing_how_to/Scarb.toml b/listings/getting-started/testing_how_to/Scarb.toml index adc0bb3b..5046ee3d 100644 --- a/listings/getting-started/testing_how_to/Scarb.toml +++ b/listings/getting-started/testing_how_to/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "testing_how_to" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/testing_how_to/src/contract.cairo b/listings/getting-started/testing_how_to/src/contract.cairo index 6eab76dd..4d125cab 100644 --- a/listings/getting-started/testing_how_to/src/contract.cairo +++ b/listings/getting-started/testing_how_to/src/contract.cairo @@ -9,11 +9,12 @@ pub trait ISimpleContract { #[starknet::contract] pub mod SimpleContract { use starknet::{get_caller_address, ContractAddress}; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; #[storage] struct Storage { - value: u32, - owner: ContractAddress + pub value: u32, + pub owner: ContractAddress } #[constructor] @@ -48,9 +49,7 @@ mod tests { // Import the deploy syscall to be able to deploy the contract. use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; - use starknet::{ - ContractAddress, get_caller_address, get_contract_address, contract_address_const - }; + use starknet::{get_contract_address, contract_address_const}; // Use starknet test utils to fake the contract_address use starknet::testing::set_contract_address; @@ -111,7 +110,7 @@ mod tests { // As the current caller is not the owner, the value cannot be set. let new_value: u32 = 20; contract.set_value(new_value); - // Panic expected + // Panic expected } #[test] @@ -125,18 +124,14 @@ mod tests { // ANCHOR: tests_with_state #[cfg(test)] mod tests_with_states { - // Only import the contract + // Only import the contract and implementation use super::SimpleContract; - - // For accessing storage variables and entrypoints, - // we must import the contract member state traits and implementation. - use SimpleContract::{ - SimpleContractImpl, valueContractMemberStateTrait, ownerContractMemberStateTrait - }; + use SimpleContract::SimpleContractImpl; use starknet::contract_address_const; use starknet::testing::set_caller_address; use core::num::traits::Zero; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; #[test] fn test_standalone_state() { @@ -145,7 +140,7 @@ mod tests_with_states { // As no contract was deployed, the constructor was not called on the state // - with valueContractMemberStateTrait assert_eq!(state.value.read(), 0); - // - with SimpleContractImpl + // - with SimpleContractImpl assert_eq!(state.get_value(), 0); assert_eq!(state.owner.read(), Zero::zero()); @@ -169,9 +164,7 @@ mod tests_with_states { // But we can also deploy the contract and interact with it using the dispatcher // as shown in the previous tests, and still use the state for testing. use super::{ISimpleContractDispatcher, ISimpleContractDispatcherTrait}; - use starknet::{ - ContractAddress, SyscallResultTrait, syscalls::deploy_syscall, testing::set_contract_address - }; + use starknet::{SyscallResultTrait, syscalls::deploy_syscall, testing::set_contract_address}; #[test] fn test_state_with_contract() { diff --git a/listings/getting-started/variables/Scarb.toml b/listings/getting-started/variables/Scarb.toml index 32b7ab20..4b6f31b2 100644 --- a/listings/getting-started/variables/Scarb.toml +++ b/listings/getting-started/variables/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "variables" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/variables/src/global_variables.cairo b/listings/getting-started/variables/src/global_variables.cairo index 1389bdaf..1e808e50 100644 --- a/listings/getting-started/variables/src/global_variables.cairo +++ b/listings/getting-started/variables/src/global_variables.cairo @@ -17,7 +17,7 @@ pub mod GlobalExample { fn foo(ref self: ContractState) { // Call the get_caller_address function to get the sender address let _caller = get_caller_address(); - // ... + // ... } } } @@ -34,6 +34,6 @@ mod test { GlobalExample::TEST_CLASS_HASH.try_into().unwrap(), 0, array![].span(), false ) .unwrap_syscall(); - // Not much to test + // Not much to test } } diff --git a/listings/getting-started/variables/src/local_variables.cairo b/listings/getting-started/variables/src/local_variables.cairo index 2bcd195d..4b2bcac5 100644 --- a/listings/getting-started/variables/src/local_variables.cairo +++ b/listings/getting-started/variables/src/local_variables.cairo @@ -22,7 +22,7 @@ pub mod LocalVariablesExample { let sum = value + increment; sum } - // We can't access the variable `sum` here, as it's out of scope. + // We can't access the variable `sum` here, as it's out of scope. } } } diff --git a/listings/getting-started/variables/src/storage_variables.cairo b/listings/getting-started/variables/src/storage_variables.cairo index e5ff96ea..864c9175 100644 --- a/listings/getting-started/variables/src/storage_variables.cairo +++ b/listings/getting-started/variables/src/storage_variables.cairo @@ -7,12 +7,15 @@ pub trait IStorageVariableExample { // ANCHOR: contract #[starknet::contract] pub mod StorageVariablesExample { + // You need to import these storage functions to read and write to storage variables + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + // All storage variables are contained in a struct called Storage // annotated with the `#[storage]` attribute #[storage] struct Storage { // Storage variable holding a number - value: u32 + pub value: u32 } #[abi(embed_v0)] @@ -34,11 +37,12 @@ pub mod StorageVariablesExample { #[cfg(test)] mod test { use super::{ - StorageVariablesExample, StorageVariablesExample::valueContractMemberStateTrait, - IStorageVariableExampleDispatcher, IStorageVariableExampleDispatcherTrait + StorageVariablesExample, IStorageVariableExampleDispatcher, + IStorageVariableExampleDispatcherTrait }; use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; use starknet::testing::set_contract_address; + use starknet::storage::StoragePointerReadAccess; #[test] fn test_can_deploy_and_mutate_storage() { @@ -55,7 +59,7 @@ mod test { assert_eq!(contract.get(), initial_value); // With contract state directly - let state = StorageVariablesExample::contract_state_for_testing(); + let state = @StorageVariablesExample::contract_state_for_testing(); set_contract_address(contract_address); assert_eq!(state.value.read(), initial_value); } diff --git a/listings/getting-started/visibility/Scarb.toml b/listings/getting-started/visibility/Scarb.toml index f589f9f5..aeadb2ef 100644 --- a/listings/getting-started/visibility/Scarb.toml +++ b/listings/getting-started/visibility/Scarb.toml @@ -1,11 +1,14 @@ [package] name = "visibility" version.workspace = true -edition = '2023_11' +edition = "2024_07" [dependencies] starknet.workspace = true +[dev-dependencies] +cairo_test.workspace = true + [scripts] test.workspace = true diff --git a/listings/getting-started/visibility/src/visibility.cairo b/listings/getting-started/visibility/src/visibility.cairo index 25256830..240b6a6c 100644 --- a/listings/getting-started/visibility/src/visibility.cairo +++ b/listings/getting-started/visibility/src/visibility.cairo @@ -7,9 +7,11 @@ pub trait IExampleContract { // ANCHOR: contract #[starknet::contract] pub mod ExampleContract { + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + #[storage] struct Storage { - value: u32 + pub value: u32 } // The `#[abi(embed_v0)]` attribute indicates that all @@ -55,11 +57,10 @@ pub mod ExampleContract { #[cfg(test)] mod test { use super::{ExampleContract, IExampleContractDispatcher, IExampleContractDispatcherTrait}; - use starknet::{ContractAddress, SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::{SyscallResultTrait, syscalls::deploy_syscall}; + use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; // These imports will allow us to directly access and set the contract state: - // - for `value` storage variable access - use super::ExampleContract::valueContractMemberStateTrait; // - for `PrivateFunctionsTrait` internal functions access // implementation need to be public to be able to access it use super::ExampleContract::PrivateFunctionsTrait; diff --git a/listings/templates/scarb/.gitignore b/listings/templates/scarb/.gitignore deleted file mode 100644 index eb5a316c..00000000 --- a/listings/templates/scarb/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target diff --git a/listings/templates/scarb/Scarb.toml b/listings/templates/scarb/Scarb.toml deleted file mode 100644 index 95266f84..00000000 --- a/listings/templates/scarb/Scarb.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "scarb" -version.workspace = true -edition = '2023_11' - -[dependencies] -starknet.workspace = true - -[scripts] -test.workspace = true - -[[target.starknet-contract]] diff --git a/listings/templates/scarb/src/lib.cairo b/listings/templates/scarb/src/lib.cairo deleted file mode 100644 index bf218399..00000000 --- a/listings/templates/scarb/src/lib.cairo +++ /dev/null @@ -1,28 +0,0 @@ -fn main() -> felt252 { - fib(16) -} - -fn fib(mut n: felt252) -> felt252 { - let mut a: felt252 = 0; - let mut b: felt252 = 1; - loop { - if n == 0 { - break a; - } - n = n - 1; - let temp = b; - b = a + b; - a = temp; - } -} - -#[cfg(test)] -mod tests { - use super::fib; - - #[test] - #[available_gas(100000)] - fn it_works() { - assert(fib(16) == 987, 'it works!'); - } -} diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 4ddbf67a..a74bd1cd 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -30,7 +30,7 @@ Summary - [Testing contracts](./getting-started/testing/contract-testing.md) - [Cairo cheatsheet](./getting-started/cairo_cheatsheet/cairo_cheatsheet.md) - [Felt](./getting-started/cairo_cheatsheet/felt.md) - - [LegacyMap](./getting-started/cairo_cheatsheet/mapping.md) + - [Map](./getting-started/cairo_cheatsheet/mapping.md) - [Arrays](./getting-started/cairo_cheatsheet/arrays.md) - [loop](./getting-started/cairo_cheatsheet/loop.md) - [while](./getting-started/cairo_cheatsheet/while.md) @@ -70,7 +70,6 @@ Summary # Advanced concepts - [Writing to any storage slot](./advanced-concepts/write_to_any_slot.md) -- [Storing Arrays](./advanced-concepts/storing_arrays.md) - [Struct as mapping key](./advanced-concepts/struct-mapping-key.md) - [Hashing](./advanced-concepts/hashing.md) @@ -79,7 +78,6 @@ Summary - [Storage Optimisations](./advanced-concepts/optimisations/store_using_packing.md) - [Account Abstraction](./advanced-concepts/account_abstraction/index.md) - [Account Contract](./advanced-concepts/account_abstraction/account_contract.md) -- [List](./advanced-concepts/list.md) - [Library Calls](./advanced-concepts/library_calls.md) - [Plugins](./advanced-concepts/plugins.md) - [Signature Verification](./advanced-concepts/signature_verification.md) diff --git a/src/advanced-concepts/list.md b/src/advanced-concepts/list.md deleted file mode 100644 index 3bcc5fa1..00000000 --- a/src/advanced-concepts/list.md +++ /dev/null @@ -1,68 +0,0 @@ -# List - -By default, there is no list type supported in Cairo, but you can use the Alexandria standard library. You can refer to the [Alexandria documentation](https://github.com/keep-starknet-strange/alexandria/tree/main/packages/storage) for more details. - -## What is `List`? - -An ordered sequence of values that can be used in Starknet storage: - -```rust -#[storage] -struct Storage { - amounts: List -} -``` - -### Interface - -```rust -trait ListTrait { - fn len(self: @List) -> u32; - fn is_empty(self: @List) -> bool; - fn append(ref self: List, value: T) -> u32; - fn get(self: @List, index: u32) -> Option; - fn set(ref self: List, index: u32, value: T); - fn pop_front(ref self: List) -> Option; - fn array(self: @List) -> Array; -} -``` - -`List` also implements `IndexView` so you can use the familiar bracket notation to access its members: - -```rust -let second = self.amounts.read()[1]; -``` - -Note that unlike `get`, using this bracket notation panics when accessing an out of bounds index. - -### Support for custom types - -`List` supports most of the corelib types out of the box. If you want to store your own custom type in a `List`, you have to implement the `Store` trait for it. You can have the compiler derive it for you using the `#[derive(starknet::Store)]` attribute. - -### Caveats - -There are two idiosyncrasies you should be aware of when using `List`: - -1. The `append` operation costs 2 storage writes - one for the value itself, and another one for updating the List's length -2. Due to a compiler limitation, it is not possible to use mutating operations with a single inline statement. For example, `self.amounts.read().append(42);` will not work. You have to do it in 2 steps: - -```rust -let mut amounts = self.amounts.read(); -amounts.append(42); -``` - -### Dependencies - -Update your project dependencies in the `Scarb.toml` file: - -```rust -[dependencies] -(...) -alexandria_storage = { git = "https://github.com/keep-starknet-strange/alexandria.git" } -``` - -For example, let's use `List` to create a contract that tracks a list of amounts and tasks: - -```rust -{{#include ../../listings/advanced-concepts/using_lists/src/contract.cairo}} -``` diff --git a/src/advanced-concepts/storing_arrays.md b/src/advanced-concepts/storing_arrays.md deleted file mode 100644 index b819dde9..00000000 --- a/src/advanced-concepts/storing_arrays.md +++ /dev/null @@ -1,19 +0,0 @@ -# Storing Arrays - -On Starknet, complex values (e.g. tuples or structs) are stored in a continuous segment starting from the address of the storage variable. There is a limitation in Cairo that restricts complex storage values to a maximum of 256 field elements. This means that to store arrays with more than 255 elements, you would have to split them into segments of size `n <= 255` and store these segments at multiple storage addresses. There is currently no native support for storing arrays in Cairo, so you would need to write your own implementation of the `Store` trait for the array type you wish to store. - -However, the `ByteArray` struct can be used to store `Array` in storage without additional implementation. Before implementing your own `Store` trait, consider wether the `ByteArray` struct can be used to store the data you need! See the [ByteArray](../getting-started/basics/bytearrays-strings.md#bytearray-long-strings) section for more information. - -> Note: While storing arrays in storage is possible, it is not always recommended, as the read and write operations can get very costly. For example, reading an array of size `n` requires `n` storage reads, and writing to an array of size `n` requires `n` storage writes. If you only need to access a single element of the array at a time, it is recommended to use a `LegacyMap` and store the length in another variable instead. - -The following example demonstrates how to write a simple implementation of the `StorageAccess` trait for the `Array` type, allowing us to store arrays of up to 255 `felt252` elements. - -```rust -{{#include ../../listings/advanced-concepts/storing_arrays/src/contract.cairo:StorageAccessImpl}} -``` - -You can then import this implementation in your contract and use it to store arrays in storage: - -```rust -{{#include ../../listings/advanced-concepts/storing_arrays/src/contract.cairo:StoreArrayContract}} -``` diff --git a/src/advanced-concepts/struct-mapping-key.md b/src/advanced-concepts/struct-mapping-key.md index 9160c2cb..72773110 100644 --- a/src/advanced-concepts/struct-mapping-key.md +++ b/src/advanced-concepts/struct-mapping-key.md @@ -1,9 +1,9 @@ # Structs as mapping keys -In order to use structs as mapping keys, you can use `#[derive(Hash)]` on the struct definition. This will automatically generate a hash function for the struct that can be used to represent the struct as a key in a `LegacyMap`. +In order to use structs as mapping keys, you can use `#[derive(Hash)]` on the struct definition. This will automatically generate a hash function for the struct that can be used to represent the struct as a key in a `Map`. Consider the following example in which we would like to use an object of -type `Pet` as a key in a `LegacyMap`. The `Pet` struct has three fields: `name`, `age` and `owner`. We consider that the combination of these three fields uniquely identifies a pet. +type `Pet` as a key in a `Map`. The `Pet` struct has three fields: `name`, `age` and `owner`. We consider that the combination of these three fields uniquely identifies a pet. ```rust {{#include ../../listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo}} diff --git a/src/applications/crowdfunding.md b/src/applications/crowdfunding.md index 8d78f05a..5257a78c 100644 --- a/src/applications/crowdfunding.md +++ b/src/applications/crowdfunding.md @@ -12,7 +12,7 @@ Crowdfunding is a method of raising capital through the collective effort of man 8. The creator can at any point cancel the campaign for whatever reason and refund all of the pledgers. 9. The contract admin can upgrade the contract implementation, refunding all of the users and reseting the campaign state (we will use this in the [Advanced Factory chapter](./advanced_factory.md)). -Because contract upgrades need to be able to refund all of the pledges, we need to be able to iterate over all of the pledgers and their amounts. Since iteration is not supported by `LegacyMap`, we need to create a custom storage type that will encompass pledge management. We use a component for this purpose. +Because contract upgrades need to be able to refund all of the pledges, we need to be able to iterate over all of the pledgers and their amounts. Since iteration is not supported by `Map`, we need to create a custom storage type that will encompass pledge management. We use a component for this purpose. ```rust {{#include ../../listings/applications/crowdfunding/src/campaign/pledgeable.cairo:component}} diff --git a/src/getting-started/basics/mappings.md b/src/getting-started/basics/mappings.md index db0b6825..d52a87f7 100644 --- a/src/getting-started/basics/mappings.md +++ b/src/getting-started/basics/mappings.md @@ -1,12 +1,12 @@ # Mappings -Maps are a key-value data structure used to store data within a smart contract. In Cairo they are implemented using the `LegacyMap` type. It's important to note that the `LegacyMap` type can only be used inside the `Storage` struct of a contract and that it can't be used elsewhere. +Maps are a key-value data structure used to store data within a smart contract. In Cairo they are implemented using the `Map` type. It's important to note that the `Map` type can only be used inside the `Storage` struct of a contract and that it can't be used elsewhere. -Here we demonstrate how to use the `LegacyMap` type within a Cairo contract, to map between a key of type `ContractAddress` and value of type `felt252`. The key-value types are specified within angular brackets <>. We write to the map by calling the `write()` method, passing in both the key and value. Similarly, we can read the value associated with a given key by calling the `read()` method and passing in the relevant key. +Here we demonstrate how to use the `Map` type within a Cairo contract, to map between a key of type `ContractAddress` and value of type `felt252`. The key-value types are specified within angular brackets <>. We write to the map by calling the `write()` method, passing in both the key and value. Similarly, we can read the value associated with a given key by calling the `read()` method and passing in the relevant key. Some additional notes: -- More complex key-value mappings are possible, for example we could use `LegacyMap::<(ContractAddress, ContractAddress), felt252>` to create an allowance on an ERC20 token contract. +- More complex key-value mappings are possible, for example we could use `Map::<(ContractAddress, ContractAddress), felt252>` to create an allowance on an ERC20 token contract. - In mappings, the address of the value at key `k_1,...,k_n` is `h(...h(h(sn_keccak(variable_name),k_1),k_2),...,k_n)` where `ℎ` is the Pedersen hash and the final value is taken \\( \bmod {2^{251}} - 256 \\). You can learn more about the contract storage layout in the [Starknet Documentation](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/contract-storage/#storage_variables). diff --git a/src/getting-started/basics/storing-custom-types.md b/src/getting-started/basics/storing-custom-types.md index ed96f088..e46c7baa 100644 --- a/src/getting-started/basics/storing-custom-types.md +++ b/src/getting-started/basics/storing-custom-types.md @@ -5,3 +5,10 @@ While native types can be stored in a contract's storage without any additional ```rust {{#rustdoc_include ../../../listings/getting-started/storing_custom_types/src/contract.cairo:contract}} ``` + +Note that it is also possible to individually access the members of the stored struct. +This is possible because deriving the `Store` trait also generates the corresponding `StoragePointer` for each member. + +```rust +{{#rustdoc_include ../../../listings/getting-started/storing_custom_types/src/contract.cairo:set_name}} +``` diff --git a/src/getting-started/cairo_cheatsheet/mapping.md b/src/getting-started/cairo_cheatsheet/mapping.md index b9ece39e..fee30ec6 100644 --- a/src/getting-started/cairo_cheatsheet/mapping.md +++ b/src/getting-started/cairo_cheatsheet/mapping.md @@ -1,6 +1,6 @@ -# `LegacyMap` +# `Map` -The `LegacyMap` type can be used to represent a collection of key-value. +The `Map` type can be used to represent a collection of key-value. ```rust {{#include ../../../listings/getting-started/cairo_cheatsheet/src/mapping_example.cairo}} diff --git a/src/starknet-by-example.md b/src/starknet-by-example.md index 962109c8..f1cff8ba 100644 --- a/src/starknet-by-example.md +++ b/src/starknet-by-example.md @@ -36,7 +36,8 @@ For more resources, check [Awesome Starknet](https://github.com/keep-starknet-st The current version this book uses: ``` -cairo 2.6.3 -edition = '2023_11' +cairo 2.8.2 +edition = "2024_07" +sierra: 1.6.0 {{#include ../.tool-versions}} ```