From 0ad395aa604b6151366c0a7b79db7df4a1d23bff Mon Sep 17 00:00:00 2001 From: Stephanie Nwankwo Date: Mon, 30 Sep 2024 10:22:38 +0100 Subject: [PATCH 1/4] feat: add the subtraction, multiplication and division functions --- assignments/assignment_3.md | 2 ++ src/lib.cairo | 63 +++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/assignments/assignment_3.md b/assignments/assignment_3.md index 2343306..7479aa8 100644 --- a/assignments/assignment_3.md +++ b/assignments/assignment_3.md @@ -5,3 +5,5 @@ - division 2. Complete [Starklings](https://starklings.app/) + + diff --git a/src/lib.cairo b/src/lib.cairo index 587aad4..579736f 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,24 +1,47 @@ fn main() { let sum_1: u8 = intro_to_uint(); let sum_2: u8 = sum_u8(2, 2); - + + let res_sub = sub(8, 5); + let res_div = div(10, 5); + let res_mult = mult(10, 2); + println!("result_1___ result_2: {} {} ", sum_1, sum_2); - } - - - fn intro_to_felt() -> felt252 { - let my_first_char: felt252 = 'GM'; - my_first_char - } - - fn intro_to_uint() -> u8 { - let x: u8 = 10; - let y: u8 = 20; - x + y - } - - fn sum_u8(x: u8, y: u8) -> u8 { - x + y - } - - \ No newline at end of file + + + println!("The subtraction result is {}", res_sub); + println!("The division result is {}", res_div); + println!("The multiplication result is {}", res_mult); +} + + +fn intro_to_felt() -> felt252 { + let my_first_char: felt252 = 'GM'; + my_first_char +} + +fn intro_to_uint() -> u8 { + let x: u8 = 10; + let y: u8 = 20; + x + y +} + +fn sum_u8(x: u8, y: u8) -> u8 { + x + y +} + +// / * - +fn sub(x: u8, y: u8) -> u8 { + x - y +} + +fn div(x: i8, y: i8) -> i8 { + x / y +} + +fn mult(x: u8, y: u8) -> u8 { + x * y +} + + +// https://starklings.app/gostean \ No newline at end of file From 55db5682184efeaeed4cbae1a2adf5e2e3678d4a Mon Sep 17 00:00:00 2001 From: Stephanie Nwankwo Date: Sat, 5 Oct 2024 11:46:35 +0100 Subject: [PATCH 2/4] ohh --- Scarb.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Scarb.toml b/Scarb.toml index d60f88b..8da58f3 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -6,11 +6,14 @@ edition = "2024_07" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -starknet = "2.8.2" +starknet = "2.8.0" +assert_macros = "2.8.0" [dev-dependencies] snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.27.0" } + [[target.starknet-contract]] +# name = "CounterV2" sierra = true From 8ba86891ec2a705bac784913dd77f698a588ded9 Mon Sep 17 00:00:00 2001 From: Stephanie Nwankwo Date: Thu, 17 Oct 2024 06:00:55 +0100 Subject: [PATCH 3/4] feat: add kill switch --- Scarb.toml | 7 +++--- src/aggregator.cairo | 57 +++++++++++++++++++++++++++---------------- src/counter.cairo | 9 ++++--- src/division.cairo | 2 +- src/kill_switch.cairo | 46 ++++++++++++++++++++++++++++++++++ src/lib.cairo | 2 ++ src/ownable.cairo | 9 ++++--- 7 files changed, 99 insertions(+), 33 deletions(-) create mode 100644 src/kill_switch.cairo diff --git a/Scarb.toml b/Scarb.toml index b8fea0e..ffe2f93 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -6,12 +6,11 @@ edition = "2023_11" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -<<<<<<< HEAD + starknet = "2.8.0" assert_macros = "2.8.0" -======= -starknet = "^2.8.4" ->>>>>>> refs/remotes/origin/main + +# starknet = "^2.8.4" [dev-dependencies] snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.31.0" } diff --git a/src/aggregator.cairo b/src/aggregator.cairo index 3d049da..bc7d590 100644 --- a/src/aggregator.cairo +++ b/src/aggregator.cairo @@ -10,70 +10,85 @@ pub trait IAggregator { fn get_counter_count(self: @T) -> u32; fn set_counter_count(ref self: T, amount: u32); - // references Counter functions fn get_aggr_owner(self: @T) -> ContractAddress; + + // killswitch + fn toggle_kill_switch(ref self: T); } #[starknet::contract] mod Aggregator { use cairo_bootcamp_3::{ counter::{ICounterDispatcher, ICounterDispatcherTrait}, - ownable::{IOwnableDispatcher, IOwnableDispatcherTrait} + ownable::{IOwnableDispatcher, IOwnableDispatcherTrait}, + kill_switch::{IKillSwitchDispatcher, IKillSwitchDispatcherTrait}, }; use super::{IAggregator}; use starknet::{ContractAddress}; - + #[storage] struct Storage { aggr_count: u32, aggr_owner: ContractAddress, ownable_addr: ContractAddress, - counter_addr: ContractAddress, + counter_addr: ContractAddress, + kill_switch_addr: ContractAddress, } #[constructor] - fn constructor(ref self: ContractState, owner_addr: ContractAddress, ownable_addr: ContractAddress, counter_addr: ContractAddress,) { + fn constructor( + ref self: ContractState, + owner_addr: ContractAddress, + ownable_addr: ContractAddress, + counter_addr: ContractAddress, + kill_switch_addr: ContractAddress + ) { self.aggr_owner.write(owner_addr); self.ownable_addr.write(ownable_addr); self.counter_addr.write(counter_addr); + self.kill_switch_addr.write(kill_switch_addr); } #[abi(embed_v0)] impl AggrImpl of IAggregator { // references Ownable contract methods // returns the address of the ownable contract - fn get_ownable_owner( - self: @ContractState, - ) -> ContractAddress { - IOwnableDispatcher { contract_address: self.ownable_addr.read()}.get_owner() + fn get_ownable_owner(self: @ContractState,) -> ContractAddress { + IOwnableDispatcher { contract_address: self.ownable_addr.read() }.get_owner() } - fn set_ownable_owner( - ref self: ContractState, new_owner: ContractAddress - ) { - IOwnableDispatcher { contract_address: self.ownable_addr.read()}.set_owner(new_owner); + fn set_ownable_owner(ref self: ContractState, new_owner: ContractAddress) { + IOwnableDispatcher { contract_address: self.ownable_addr.read() }.set_owner(new_owner); } // references Counter contract methods fn get_counter_count(self: @ContractState) -> u32 { - ICounterDispatcher { contract_address: self.counter_addr.read()}.get_count() + ICounterDispatcher { contract_address: self.counter_addr.read() }.get_count() } - fn set_counter_count( - ref self: ContractState, amount: u32 - ) { - ICounterDispatcher { contract_address: self.counter_addr.read()}.set_count(amount); + fn set_counter_count(ref self: ContractState, amount: u32) { + let kill_switch = IKillSwitchDispatcher { + contract_address: self.kill_switch_addr.read() + }; + assert(kill_switch.get_state(), 'Kill switch is off'); + ICounterDispatcher { contract_address: self.counter_addr.read() }.set_count(amount); } fn get_aggr_owner(self: @ContractState) -> ContractAddress { self.aggr_owner.read() } + + fn toggle_kill_switch(ref self: ContractState) { + let killswitch = IKillSwitchDispatcher { + contract_address: self.kill_switch_addr.read() + }; + killswitch.toggle(); + } } } - -// 0x1dd6e81d875e3451d14d418af0f42464bbaec19127465e700fb07cb403eb4cc - ca - +// 0x166dc997ccec20d33b3792fa3a60a3c97c1781521ad5dfa02f270d08f4aef60 - ca +/// 0x16d60fafe0c39706e812ef96360ac03ee0feb8387efc9fddc70b5b1c6fd5a47 --- clash-hash diff --git a/src/counter.cairo b/src/counter.cairo index 2b50844..89b0795 100644 --- a/src/counter.cairo +++ b/src/counter.cairo @@ -28,7 +28,10 @@ mod Counter { } } } -// 0x0726aae552474f128529c982392e8490c496395c1a2d7879c029203ad12e97bb +// 0x0128fe1941a77f17abba960d33e491036cb7c607b23cbbc49abecda8e80fc3c1 --- class hash + +/// 0x66043c0e51ad08ee2d9861a66c15de5b78ca483f5b211b5437a4c4c9fd4e3eb -- cohort_dev address +//__________________________________TODAY_______________________ +// 0x20345aad7d3082f69cfda059f8e06d031a912107478fbc68df5dad4298bc8f1 - counter ca + -//__________________________________TODAY_______________________ -// 0x45f8e8b3d6ecf220d78fdc13a523ae8ecaa90581ee68baa958d8ba3181841e9 - counter ca \ No newline at end of file diff --git a/src/division.cairo b/src/division.cairo index f293d58..fcb4b25 100644 --- a/src/division.cairo +++ b/src/division.cairo @@ -1,3 +1,3 @@ pub fn div(x: i8, y: i8) -> i8 { x / y -} \ No newline at end of file +} diff --git a/src/kill_switch.cairo b/src/kill_switch.cairo new file mode 100644 index 0000000..0f8993a --- /dev/null +++ b/src/kill_switch.cairo @@ -0,0 +1,46 @@ +#[starknet::interface] +pub trait IKillSwitch { + fn toggle(ref self: TContractState); + fn get_state(self: @TContractState) -> bool; +} + +#[starknet::contract] +mod KillSwitch { + #[storage] + struct Storage { + is_on: bool, + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + KillSwitchToggled: KillSwitchToggled, + } + + #[derive(Drop, starknet::Event)] + struct KillSwitchToggled { + new_state: bool, + } + + #[constructor] + fn constructor(ref self: ContractState) { + self.is_on.write(true); + } + + #[abi(embed_v0)] + impl KillSwitchImpl of super::IKillSwitch { + fn toggle(ref self: ContractState) { + let current_state = self.is_on.read(); + let new_state = !current_state; + self.is_on.write(new_state); + self.emit(KillSwitchToggled { new_state }); + } + + fn get_state(self: @ContractState) -> bool { + self.is_on.read() + } + } +} +/// 0x3e138694770f2a1586c403ff5c8283258346565e274a01989984fe023157c7d class hash +/// 0x58d629f09fc3a79331ed1689c1c6ab9c2f025c4f0caff879b1d5acf0eab44d9 KA + diff --git a/src/lib.cairo b/src/lib.cairo index 5b2423b..9912d20 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -9,3 +9,5 @@ pub mod ownable_counter; pub mod ownable; pub mod addition; +pub mod kill_switch; +pub mod aggregator; diff --git a/src/ownable.cairo b/src/ownable.cairo index a3e7b14..bd38ea3 100644 --- a/src/ownable.cairo +++ b/src/ownable.cairo @@ -47,9 +47,10 @@ mod Ownable { // 0x6331d7d1cb9bc762785d083570d0d594fcf57cf3e5384209b59435c3f7e6d8b -- justice - - -//__________________________________TODAY_______________________ +//__________________________________TODAY_______________________ // 0xdedef0be763547e8e505d12fac321d0de4e9bd51635ac5fa00ae61d12e463e // 0x6f2f6eb269f9741d5bb9cb633bfb632a0d71e0622b195ef4c4e66e8f1fee9fe - deploy_dev account -// 0x2a601649affa4fb870f919058baeed96729b1d7be7282b978e5ba50852d7c77 - ownable ca \ No newline at end of file +// 0x2a601649affa4fb870f919058baeed96729b1d7be7282b978e5ba50852d7c77 - ownable ca + +/// 0x00dedef0be763547e8e505d12fac321d0de4e9bd51635ac5fa00ae61d12e463e class - hash + From da2894c74d04e26c287461baffd4c2931fad40c8 Mon Sep 17 00:00:00 2001 From: Stephanie Nwankwo Date: Thu, 17 Oct 2024 09:19:33 +0100 Subject: [PATCH 4/4] feat(test_kill_witch): add test for kill switch --- src/aggregator.cairo | 1 + src/kill_switch.cairo | 1 + src/ownable.cairo | 1 + tests/test_aggregatoe.cairo | 115 ++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 tests/test_aggregatoe.cairo diff --git a/src/aggregator.cairo b/src/aggregator.cairo index bc7d590..4c0d91c 100644 --- a/src/aggregator.cairo +++ b/src/aggregator.cairo @@ -92,3 +92,4 @@ mod Aggregator { /// 0x16d60fafe0c39706e812ef96360ac03ee0feb8387efc9fddc70b5b1c6fd5a47 --- clash-hash + diff --git a/src/kill_switch.cairo b/src/kill_switch.cairo index 0f8993a..ca11903 100644 --- a/src/kill_switch.cairo +++ b/src/kill_switch.cairo @@ -44,3 +44,4 @@ mod KillSwitch { /// 0x3e138694770f2a1586c403ff5c8283258346565e274a01989984fe023157c7d class hash /// 0x58d629f09fc3a79331ed1689c1c6ab9c2f025c4f0caff879b1d5acf0eab44d9 KA + diff --git a/src/ownable.cairo b/src/ownable.cairo index bd38ea3..4939bdd 100644 --- a/src/ownable.cairo +++ b/src/ownable.cairo @@ -54,3 +54,4 @@ mod Ownable { /// 0x00dedef0be763547e8e505d12fac321d0de4e9bd51635ac5fa00ae61d12e463e class - hash + diff --git a/tests/test_aggregatoe.cairo b/tests/test_aggregatoe.cairo new file mode 100644 index 0000000..18577aa --- /dev/null +++ b/tests/test_aggregatoe.cairo @@ -0,0 +1,115 @@ +use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; +use starknet::{ContractAddress}; +use cairo_bootcamp_3::aggregator::{IAggregatorDispatcher, IAggregatorDispatcherTrait}; + +pub mod Accounts { + use starknet::ContractAddress; + use core::traits::TryInto; + + pub fn zero() -> ContractAddress { + 0x0000000000000000000000000000000000000000.try_into().unwrap() + } + + pub fn owner() -> ContractAddress { + 'owner'.try_into().unwrap() + } + + pub fn account1() -> ContractAddress { + 'account1'.try_into().unwrap() + } + + pub fn account2() -> ContractAddress { + 'account2'.try_into().unwrap() + } + + pub fn account3() -> ContractAddress { + 'account3'.try_into().unwrap() + } + pub fn account4() -> ContractAddress { + 'account4'.try_into().unwrap() + } +} + +fn deploy(name: ByteArray) -> ContractAddress { + // Deploy Ownable contract + let ownable_contract = declare("Ownable").unwrap().contract_class(); + let (ownable_address, _) = ownable_contract.deploy(@array![Accounts::owner().into()]).unwrap(); + + // Deploy Counter contract + let counter_contract = declare("Counter").unwrap().contract_class(); + let (counter_address, _) = counter_contract.deploy(@array![]).unwrap(); + + // Deploy KillSwitch contract + let kill_switch_contract = declare("KillSwitch").unwrap().contract_class(); + let (kill_switch_address, _) = kill_switch_contract.deploy(@array![]).unwrap(); + + // Deploy Aggregator contract + let aggregator_contract = declare(name).unwrap().contract_class(); + let constructor_args = array![ + Accounts::owner().into(), + ownable_address.into(), + counter_address.into(), + kill_switch_address.into() + ]; + let (contract_address, _) = aggregator_contract.deploy(@constructor_args).unwrap(); + contract_address +} + +#[test] +fn test_get_aggr_count() { + // Deploy Counter contract and get the contract address + let contract_address = deploy("Aggregator"); + + // Get an instance of the deployed Counter contract + let aggregator_dispatcher = IAggregatorDispatcher { contract_address }; + + let initial_count = aggregator_dispatcher.get_counter_count(); + + assert_eq!(initial_count, 0); + + aggregator_dispatcher.set_counter_count(5); + let current_count = aggregator_dispatcher.get_counter_count(); + assert_eq!(current_count, 5); +} + +#[test] +fn test_aggr_owner_was_set_correctly() { + // Deploy Counter contract and get the contract address + let contract_address = deploy("Aggregator"); + + // Get an instance of the deployed Counter contract + let aggregator_dispatcher = IAggregatorDispatcher { contract_address }; + + let current_owner = aggregator_dispatcher.get_aggr_owner(); + assert_eq!(current_owner, Accounts::owner()); +} + + +#[test] +fn test_counter() {} + +#[test] +fn test_set_count_correctly() { + let contract_address = deploy("Aggregator"); + let aggregator_dispatcher = IAggregatorDispatcher { contract_address }; + + aggregator_dispatcher.set_counter_count(42); + let count = aggregator_dispatcher.get_counter_count(); + assert_eq!(count, 42, "Count should be set to 42"); +} + +#[test] +#[should_panic(expected: ('Kill switch is off',))] +fn test_can_not_set_count_when_toggle_is_off() { + let contract_address = deploy("Aggregator"); + let aggregator_dispatcher = IAggregatorDispatcher { contract_address }; + + // Toggle the kill switch off + aggregator_dispatcher.toggle_kill_switch(); + + // This should panic because the kill switch is off + aggregator_dispatcher.set_counter_count(10); +} + + +