diff --git a/.github/workflows/test_contract.yml b/.github/workflows/test_contract.yml index 434bbcb..0804bad 100644 --- a/.github/workflows/test_contract.yml +++ b/.github/workflows/test_contract.yml @@ -39,4 +39,19 @@ jobs: - name: Check formatting run: | - scarb fmt --check \ No newline at end of file + scarb fmt --check + + - name: Check formatting in cloakpay + run: | + cd cloakpay + scarb fmt --check + + - name: Build contracts in cloakpay + run: | + cd cloakpay + scarb build + + - name: Run tests in cloakpay + run: | + cd cloakpay + snforge test diff --git a/cloakpay/.gitignore b/cloakpay/.gitignore new file mode 100644 index 0000000..4096f8b --- /dev/null +++ b/cloakpay/.gitignore @@ -0,0 +1,5 @@ +target +.snfoundry_cache/ +snfoundry_trace/ +coverage/ +profile/ diff --git a/cloakpay/CONTRIBUTION.md b/cloakpay/CONTRIBUTION.md new file mode 100644 index 0000000..8418105 --- /dev/null +++ b/cloakpay/CONTRIBUTION.md @@ -0,0 +1,33 @@ +# Contributing to CloakPay + +Thank you for your interest in contributing to this project! + +## Getting Started + +1. **Fork the repository** and clone it to your local machine. +2. **Install dependencies** as required by the project. + +## Development Workflow + +- **Format code:** + Run `scarb fmt` to format the codebase. + +- **Build the project:** + Run `scarb build` to build the project. + +- **Run tests:** + Run `snforge test` to execute the test suite. + +## Pull Requests + +- Ensure your code is well-formatted and passes all tests. +- Provide clear commit messages and describe your changes in the pull request. +- Reference related issues if applicable. + +## Code of Conduct + +Please be respectful and considerate in all interactions. + +--- + +Happy coding! \ No newline at end of file diff --git a/cloakpay/Scarb.lock b/cloakpay/Scarb.lock new file mode 100644 index 0000000..bed552f --- /dev/null +++ b/cloakpay/Scarb.lock @@ -0,0 +1,24 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "cloakpay" +version = "0.1.0" +dependencies = [ + "snforge_std", +] + +[[package]] +name = "snforge_scarb_plugin" +version = "0.40.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:7c3b21f6cdab14fc63e19f9e6789b6a3d44f5618ebcf02d03b397375304e1891" + +[[package]] +name = "snforge_std" +version = "0.40.0" +source = "registry+https://scarbs.xyz/" +checksum = "sha256:0221bbe959eec72eb2e30be68df66c4ff5dcd924ec491f285c974e49671fabc0" +dependencies = [ + "snforge_scarb_plugin", +] diff --git a/cloakpay/Scarb.toml b/cloakpay/Scarb.toml new file mode 100644 index 0000000..7079fb1 --- /dev/null +++ b/cloakpay/Scarb.toml @@ -0,0 +1,52 @@ +[package] +name = "cloakpay" +version = "0.1.0" +edition = "2024_07" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.11.2" + +[dev-dependencies] +snforge_std = "0.40.0" +assert_macros = "2.11.2" + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" + +[tool.scarb] +allow-prebuilt-plugins = ["snforge_std"] + +# Visit https://foundry-rs.github.io/starknet-foundry/appendix/scarb-toml.html for more information + +# [tool.snforge] # Define `snforge` tool section +# exit_first = true # Stop tests execution immediately upon the first failure +# fuzzer_runs = 1234 # Number of runs of the random fuzzer +# fuzzer_seed = 1111 # Seed for the random fuzzer + +# [[tool.snforge.fork]] # Used for fork testing +# name = "SOME_NAME" # Fork name +# url = "http://your.rpc.url" # Url of the RPC provider +# block_id.tag = "latest" # Block to fork from (block tag) + +# [[tool.snforge.fork]] +# name = "SOME_SECOND_NAME" +# url = "http://your.second.rpc.url" +# block_id.number = "123" # Block to fork from (block number) + +# [[tool.snforge.fork]] +# name = "SOME_THIRD_NAME" +# url = "http://your.third.rpc.url" +# block_id.hash = "0x123" # Block to fork from (block hash) + +# [profile.dev.cairo] # Configure Cairo compiler +# unstable-add-statements-code-locations-debug-info = true # Should be used if you want to use coverage +# unstable-add-statements-functions-debug-info = true # Should be used if you want to use coverage/profiler +# inlining-strategy = "avoid" # Should be used if you want to use coverage + +# [features] # Used for conditional compilation +# enable_for_tests = [] # Feature name and list of other features that should be enabled with it diff --git a/cloakpay/snfoundry.toml b/cloakpay/snfoundry.toml new file mode 100644 index 0000000..78c7789 --- /dev/null +++ b/cloakpay/snfoundry.toml @@ -0,0 +1,11 @@ +# Visit https://foundry-rs.github.io/starknet-foundry/appendix/snfoundry-toml.html +# and https://foundry-rs.github.io/starknet-foundry/projects/configuration.html for more information + +# [sncast.default] # Define a profile name +# url = "https://free-rpc.nethermind.io/sepolia-juno/v0_8" # Url of the RPC provider +# accounts-file = "../account-file" # Path to the file with the account data +# account = "mainuser" # Account from `accounts_file` or default account file that will be used for the transactions +# keystore = "~/keystore" # Path to the keystore file +# wait-params = { timeout = 300, retry-interval = 10 } # Wait for submitted transaction parameters +# block-explorer = "StarkScan" # Block explorer service used to display links to transaction details +# show-explorer-links = true # Print links pointing to pages with transaction details in the chosen block explorer diff --git a/cloakpay/src/lib.cairo b/cloakpay/src/lib.cairo new file mode 100644 index 0000000..8f5ae7d --- /dev/null +++ b/cloakpay/src/lib.cairo @@ -0,0 +1,32 @@ +/// Interface representing `HelloContract`. +/// This interface allows modification and retrieval of the contract balance. +#[starknet::interface] +pub trait IHelloStarknet { + /// Increase contract balance. + fn increase_balance(ref self: TContractState, amount: felt252); + /// Retrieve contract balance. + fn get_balance(self: @TContractState) -> felt252; +} + +/// Simple contract for managing balance. +#[starknet::contract] +mod HelloStarknet { + use core::starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; + + #[storage] + struct Storage { + balance: felt252, + } + + #[abi(embed_v0)] + impl HelloStarknetImpl of super::IHelloStarknet { + fn increase_balance(ref self: ContractState, amount: felt252) { + assert(amount != 0, 'Amount cannot be 0'); + self.balance.write(self.balance.read() + amount); + } + + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + } +} diff --git a/cloakpay/tests/test_contract.cairo b/cloakpay/tests/test_contract.cairo new file mode 100644 index 0000000..14fecd4 --- /dev/null +++ b/cloakpay/tests/test_contract.cairo @@ -0,0 +1,45 @@ +use cloakpay::{ + IHelloStarknetDispatcher, IHelloStarknetDispatcherTrait, IHelloStarknetSafeDispatcher, + IHelloStarknetSafeDispatcherTrait, +}; +use snforge_std::{ContractClassTrait, DeclareResultTrait, declare}; +use starknet::ContractAddress; + +fn deploy_contract(name: ByteArray) -> ContractAddress { + let contract = declare(name).unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@ArrayTrait::new()).unwrap(); + contract_address +} + +#[test] +fn test_increase_balance() { + let contract_address = deploy_contract("HelloStarknet"); + + let dispatcher = IHelloStarknetDispatcher { contract_address }; + + let balance_before = dispatcher.get_balance(); + assert(balance_before == 0, 'Invalid balance'); + + dispatcher.increase_balance(42); + + let balance_after = dispatcher.get_balance(); + assert(balance_after == 42, 'Invalid balance'); +} + +#[test] +#[feature("safe_dispatcher")] +fn test_cannot_increase_balance_with_zero_value() { + let contract_address = deploy_contract("HelloStarknet"); + + let safe_dispatcher = IHelloStarknetSafeDispatcher { contract_address }; + + let balance_before = safe_dispatcher.get_balance().unwrap(); + assert(balance_before == 0, 'Invalid balance'); + + match safe_dispatcher.increase_balance(0) { + Result::Ok(_) => core::panic_with_felt252('Should have panicked'), + Result::Err(panic_data) => { + assert(*panic_data.at(0) == 'Amount cannot be 0', *panic_data.at(0)); + }, + }; +}