From eb153da7f88b60ba5742df626442759f20387464 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Tue, 10 Sep 2024 17:15:38 +0800 Subject: [PATCH] additionnal tests --- contracts/.snfoundry_cache/.prev_tests_failed | 1 - contracts/.tool-versions | 2 +- contracts/src/components/escrow/escrow.cairo | 5 +- .../src/components/escrow/escrow_test.cairo | 141 ++++++++++++++++-- .../src/components/escrow/interface.cairo | 8 +- .../src/components/processors/tls/tls.cairo | 12 +- .../src/components/registry/interface.cairo | 4 +- .../src/components/registry/registry.cairo | 4 +- .../components/registry/registry_test.cairo | 8 +- .../nullifier_registry.cairo | 8 +- .../revolut/revolut_send_processor.cairo | 4 +- contracts/src/tests/constants.cairo | 8 + contracts/src/utils/hash.cairo | 4 +- 13 files changed, 154 insertions(+), 55 deletions(-) diff --git a/contracts/.snfoundry_cache/.prev_tests_failed b/contracts/.snfoundry_cache/.prev_tests_failed index 385a063..e69de29 100644 --- a/contracts/.snfoundry_cache/.prev_tests_failed +++ b/contracts/.snfoundry_cache/.prev_tests_failed @@ -1 +0,0 @@ -zkramp::components::escrow::escrow_test::test_lock_unlock diff --git a/contracts/.tool-versions b/contracts/.tool-versions index 045dc3e..ab54af5 100644 --- a/contracts/.tool-versions +++ b/contracts/.tool-versions @@ -1 +1 @@ -scarb 2.7.0 +scarb 2.8.0 diff --git a/contracts/src/components/escrow/escrow.cairo b/contracts/src/components/escrow/escrow.cairo index f5fe85f..a5a9b9c 100644 --- a/contracts/src/components/escrow/escrow.cairo +++ b/contracts/src/components/escrow/escrow.cairo @@ -62,10 +62,7 @@ pub mod EscrowComponent { TContractState, +HasComponent, +Drop, > of interface::IEscrow> { fn lock_from( - ref self: ComponentState, - from: ContractAddress, - token: ContractAddress, - amount: u256 + ref self: ComponentState, from: ContractAddress, token: ContractAddress, amount: u256 ) { let locked_amount = self.deposits.read((from, token)); diff --git a/contracts/src/components/escrow/escrow_test.cairo b/contracts/src/components/escrow/escrow_test.cairo index 1fc9bb3..1071926 100644 --- a/contracts/src/components/escrow/escrow_test.cairo +++ b/contracts/src/components/escrow/escrow_test.cairo @@ -1,10 +1,9 @@ use core::starknet::get_contract_address; use openzeppelin::presets::interfaces::ERC20UpgradeableABIDispatcherTrait; - -use zkramp::components::escrow::escrow::EscrowComponent::EscrowImpl; +use snforge_std::{start_cheat_caller_address, EventSpyAssertionsTrait, spy_events}; +use zkramp::components::escrow::escrow::EscrowComponent::{Event, Locked, UnLocked, EscrowImpl}; use zkramp::components::escrow::escrow_mock::{TestingStateDefault, ComponentState}; - use zkramp::tests::constants; use zkramp::tests::utils; @@ -13,18 +12,142 @@ use zkramp::tests::utils; // Externals // +#[test] +fn test_lock() { + let mut spy = spy_events(); + let token_dispatcher = utils::setup_erc20(recipient: constants::OWNER()); + start_cheat_caller_address(token_dispatcher.contract_address, constants::OWNER()); + + token_dispatcher.transfer(constants::SPENDER(), 100); + + start_cheat_caller_address(token_dispatcher.contract_address, constants::SPENDER()); + + token_dispatcher.approve(constants::RECIPIENT(), 42); + start_cheat_caller_address(token_dispatcher.contract_address, constants::RECIPIENT()); + + let mut escrow: ComponentState = Default::default(); + + escrow.lock_from(constants::SPENDER(), token_dispatcher.contract_address, 42); + + assert_eq!(token_dispatcher.balance_of(constants::SPENDER()), 58); + assert_eq!(token_dispatcher.allowance(constants::SPENDER(), constants::RECIPIENT()), 0); + + // test event emission + spy + .assert_emitted( + @array![ + ( + get_contract_address(), + Event::Locked( + Locked { token: token_dispatcher.contract_address, from: constants::SPENDER(), amount: 42 } + ) + ) + ] + ) +} + + #[test] fn test_lock_unlock() { - let token_dispatcher = utils::setup_erc20(recipient: get_contract_address()); + let mut spy = spy_events(); + let token_dispatcher = utils::setup_erc20(recipient: constants::OWNER()); + start_cheat_caller_address(token_dispatcher.contract_address, constants::OWNER()); - token_dispatcher.transfer(constants::OWNER(), 100); + token_dispatcher.transfer(constants::SPENDER(), 100); + + start_cheat_caller_address(token_dispatcher.contract_address, constants::SPENDER()); + + token_dispatcher.approve(constants::RECIPIENT(), 42); + start_cheat_caller_address(token_dispatcher.contract_address, constants::RECIPIENT()); let mut escrow: ComponentState = Default::default(); - escrow.lock_from(constants::OWNER(), token_dispatcher.contract_address, 42); + escrow.lock_from(constants::SPENDER(), token_dispatcher.contract_address, 42); + + start_cheat_caller_address(token_dispatcher.contract_address, get_contract_address()); - escrow - .unlock_to(constants::OWNER(), constants::CALLER(), token_dispatcher.contract_address, 42); + token_dispatcher.approve(constants::RECIPIENT(), 42); + + start_cheat_caller_address(token_dispatcher.contract_address, constants::RECIPIENT()); + escrow.unlock_to(constants::SPENDER(), constants::RECIPIENT(), token_dispatcher.contract_address, 42); + + assert_eq!(token_dispatcher.balance_of(constants::SPENDER()), 58); + assert_eq!(token_dispatcher.balance_of(constants::RECIPIENT()), 42); + assert_eq!(token_dispatcher.allowance(constants::SPENDER(), constants::RECIPIENT()), 0); + assert_eq!(escrow.deposits.read((constants::SPENDER(), token_dispatcher.contract_address)), 0); + + // test event emission + spy + .assert_emitted( + @array![ + ( + get_contract_address(), + Event::Locked( + Locked { token: token_dispatcher.contract_address, from: constants::SPENDER(), amount: 42 } + ) + ) + ] + ); + + spy + .assert_emitted( + @array![ + ( + get_contract_address(), + Event::UnLocked( + UnLocked { + token: token_dispatcher.contract_address, + from: constants::SPENDER(), + to: constants::RECIPIENT(), + amount: 42 + } + ) + ) + ] + ) +} + + +#[test] +#[should_panic(expected: 'Insufficient deposit balance')] +fn test_lock_unlock_greater_than_balance() { + let token_dispatcher = utils::setup_erc20(recipient: constants::OWNER()); + start_cheat_caller_address(token_dispatcher.contract_address, constants::OWNER()); + + token_dispatcher.transfer(constants::SPENDER(), 1000); + + start_cheat_caller_address(token_dispatcher.contract_address, constants::SPENDER()); + + token_dispatcher.approve(constants::RECIPIENT(), 42); + start_cheat_caller_address(token_dispatcher.contract_address, constants::RECIPIENT()); + + let mut escrow: ComponentState = Default::default(); + + escrow.lock_from(constants::SPENDER(), token_dispatcher.contract_address, 42); + + start_cheat_caller_address(token_dispatcher.contract_address, get_contract_address()); + + token_dispatcher.approve(constants::RECIPIENT(), 42); + + start_cheat_caller_address(token_dispatcher.contract_address, constants::RECIPIENT()); + escrow.unlock_to(constants::SPENDER(), constants::RECIPIENT(), token_dispatcher.contract_address, 420); +} + +#[test] +#[should_panic(expected: 'ERC20: insufficient allowance')] +fn test_lock_from_unallowed_caller() { + let token_dispatcher = utils::setup_erc20(recipient: constants::OWNER()); + start_cheat_caller_address(token_dispatcher.contract_address, constants::OWNER()); + + token_dispatcher.transfer(constants::SPENDER(), 100); + + start_cheat_caller_address(token_dispatcher.contract_address, constants::SPENDER()); + + token_dispatcher.approve(constants::RECIPIENT(), 42); + + start_cheat_caller_address(token_dispatcher.contract_address, constants::CALLER()); + + let mut escrow: ComponentState = Default::default(); - assert_eq!(escrow.deposits.read((constants::OWNER(), token_dispatcher.contract_address)), 0); + escrow.lock_from(constants::SPENDER(), token_dispatcher.contract_address, 42); } diff --git a/contracts/src/components/escrow/interface.cairo b/contracts/src/components/escrow/interface.cairo index f39af37..5539145 100644 --- a/contracts/src/components/escrow/interface.cairo +++ b/contracts/src/components/escrow/interface.cairo @@ -3,11 +3,5 @@ use starknet::ContractAddress; #[starknet::interface] pub trait IEscrow { fn lock_from(ref self: TState, from: ContractAddress, token: ContractAddress, amount: u256); - fn unlock_to( - ref self: TState, - from: ContractAddress, - to: ContractAddress, - token: ContractAddress, - amount: u256 - ); + fn unlock_to(ref self: TState, from: ContractAddress, to: ContractAddress, token: ContractAddress, amount: u256); } diff --git a/contracts/src/components/processors/tls/tls.cairo b/contracts/src/components/processors/tls/tls.cairo index 3597c8b..5ab68be 100644 --- a/contracts/src/components/processors/tls/tls.cairo +++ b/contracts/src/components/processors/tls/tls.cairo @@ -51,9 +51,7 @@ pub mod TLSProcessorComponent { /// /// @param timestamp_buffer The timestamp buffer for validated TLS calls /// - fn set_timestamp_buffer( - ref self: ComponentState, timestamp_buffer: felt252 - ) { + fn set_timestamp_buffer(ref self: ComponentState, timestamp_buffer: felt252) { // assert only owner let mut ownable_component = get_dep_component!(@self, Ownable); ownable_component.assert_only_owner(); @@ -101,9 +99,7 @@ pub mod TLSProcessorComponent { assert(expected_endpoint == endpoint, Errors::BAD_ENDPOINT); } - fn _validate_TLS_host( - self: @ComponentState, expected_host: ByteArray, host: ByteArray - ) { + fn _validate_TLS_host(self: @ComponentState, expected_host: ByteArray, host: ByteArray) { assert(expected_host == host, Errors::BAD_HOST); } @@ -114,9 +110,7 @@ pub mod TLSProcessorComponent { nullifier_registry.add_nullifier(:nullifier); } - fn _validate_signature( - self: @ComponentState, - ) { // TODO: verifiy signature, can we use SNIP-12? + fn _validate_signature(self: @ComponentState,) { // TODO: verifiy signature, can we use SNIP-12? } } } diff --git a/contracts/src/components/registry/interface.cairo b/contracts/src/components/registry/interface.cairo index 6999934..fcc79e7 100644 --- a/contracts/src/components/registry/interface.cairo +++ b/contracts/src/components/registry/interface.cairo @@ -8,8 +8,6 @@ pub enum OffchainId { #[starknet::interface] pub trait IRegistry { - fn is_registered( - self: @TState, contract_address: ContractAddress, offchain_id: OffchainId - ) -> bool; + fn is_registered(self: @TState, contract_address: ContractAddress, offchain_id: OffchainId) -> bool; fn register(ref self: TState, offchain_id: OffchainId); } diff --git a/contracts/src/components/registry/registry.cairo b/contracts/src/components/registry/registry.cairo index 24f43c6..2621bf6 100644 --- a/contracts/src/components/registry/registry.cairo +++ b/contracts/src/components/registry/registry.cairo @@ -49,9 +49,7 @@ pub mod RegistryComponent { TContractState, +HasComponent, +Drop, > of interface::IRegistry> { fn is_registered( - self: @ComponentState, - contract_address: ContractAddress, - offchain_id: OffchainId + self: @ComponentState, contract_address: ContractAddress, offchain_id: OffchainId ) -> bool { self.Registry_registrations.read((contract_address, offchain_id)) } diff --git a/contracts/src/components/registry/registry_test.cairo b/contracts/src/components/registry/registry_test.cairo index 0732fdd..eb31e00 100644 --- a/contracts/src/components/registry/registry_test.cairo +++ b/contracts/src/components/registry/registry_test.cairo @@ -1,8 +1,6 @@ use core::starknet::ContractAddress; use snforge_std::{start_cheat_caller_address, EventSpyAssertionsTrait, spy_events, test_address}; -use zkramp::components::registry::registry::{ - RegistryComponent::{Event, RegistrationEvent, RegistryImpl} -}; +use zkramp::components::registry::registry::{RegistryComponent::{Event, RegistrationEvent, RegistryImpl}}; use zkramp::components::registry::registry_mock::{TestingStateDefault, ComponentState}; use zkramp::tests::constants; @@ -40,9 +38,7 @@ fn test_registration_event() { ( test_address, Event::RegistrationEvent( - RegistrationEvent { - caller: constants::CALLER(), offchain_id: constants::REVOLUT_ID() - } + RegistrationEvent { caller: constants::CALLER(), offchain_id: constants::REVOLUT_ID() } ) ) ] diff --git a/contracts/src/contracts/nullifier_registry/nullifier_registry.cairo b/contracts/src/contracts/nullifier_registry/nullifier_registry.cairo index 398d56f..e8b7356 100644 --- a/contracts/src/contracts/nullifier_registry/nullifier_registry.cairo +++ b/contracts/src/contracts/nullifier_registry/nullifier_registry.cairo @@ -131,9 +131,7 @@ pub mod NullifierRegistry { #[cfg(test)] mod NullifierRegistry_tests { use core::traits::Into; - use snforge_std::{ - declare, ContractClassTrait, start_cheat_caller_address, stop_cheat_caller_address - }; + use snforge_std::{declare, ContractClassTrait, start_cheat_caller_address, stop_cheat_caller_address}; use starknet::{ContractAddress}; use zkramp::contracts::nullifier_registry::interface::{ INullifierRegistryDispatcher, INullifierRegistryDispatcherTrait @@ -145,9 +143,7 @@ mod NullifierRegistry_tests { fn deploy_NullifierRegistry(owner: felt252) -> ContractAddress { let mut nullifier_constructor_calldata = array![owner]; let mut nullifier_contract = declare("NullifierRegistry").unwrap(); - let (contract_address, _) = nullifier_contract - .deploy(@nullifier_constructor_calldata) - .unwrap(); + let (contract_address, _) = nullifier_contract.deploy(@nullifier_constructor_calldata).unwrap(); contract_address } diff --git a/contracts/src/contracts/ramps/revolut/revolut_send_processor.cairo b/contracts/src/contracts/ramps/revolut/revolut_send_processor.cairo index 8eb3709..a50ef6b 100644 --- a/contracts/src/contracts/ramps/revolut/revolut_send_processor.cairo +++ b/contracts/src/contracts/ramps/revolut/revolut_send_processor.cairo @@ -59,8 +59,6 @@ pub mod RevolutSendProcessor { self.ownable.initializer(:owner); // initialize TLS processor - self - .tls_processor - .initializer(:ramp_address, :nullifier_registry, :timestamp_buffer, :enpoint, :host); + self.tls_processor.initializer(:ramp_address, :nullifier_registry, :timestamp_buffer, :enpoint, :host); } } diff --git a/contracts/src/tests/constants.cairo b/contracts/src/tests/constants.cairo index 6850b0e..9a12b7e 100644 --- a/contracts/src/tests/constants.cairo +++ b/contracts/src/tests/constants.cairo @@ -13,6 +13,14 @@ pub fn CALLER() -> ContractAddress { contract_address_const::<'caller'>() } +pub fn SPENDER() -> ContractAddress { + contract_address_const::<'soender'>() +} + +pub fn RECIPIENT() -> ContractAddress { + contract_address_const::<'recipient'>() +} + pub fn OWNER() -> ContractAddress { contract_address_const::<'owner'>() } diff --git a/contracts/src/utils/hash.cairo b/contracts/src/utils/hash.cairo index 6dc133a..a6ad033 100644 --- a/contracts/src/utils/hash.cairo +++ b/contracts/src/utils/hash.cairo @@ -2,9 +2,7 @@ use core::hash::{HashStateTrait, Hash}; // Care must be taken when using this implementation: Serde of the type T must be safe for hashing. // This means that no two values of type T have the same serialization. -pub(crate) impl HashSerializable< - T, S, +Serde, +HashStateTrait, +Drop, +Drop -> of Hash { +pub(crate) impl HashSerializable, +HashStateTrait, +Drop, +Drop> of Hash { fn update_state(mut state: S, value: T) -> S { let mut arr = array![]; Serde::serialize(@value, ref arr);