diff --git a/Scarb.toml b/Scarb.toml index dda5551..ffe2f93 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -6,13 +6,19 @@ edition = "2023_11" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -starknet = "^2.8.4" + +starknet = "2.8.0" +assert_macros = "2.8.0" + +# starknet = "^2.8.4" [dev-dependencies] snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.31.0" } assert_macros = "2.8.4" + [[target.starknet-contract]] +# name = "CounterV2" sierra = true [scripts] diff --git a/src/aggregator.cairo b/src/aggregator.cairo index 3d049da..4c0d91c 100644 --- a/src/aggregator.cairo +++ b/src/aggregator.cairo @@ -10,70 +10,86 @@ 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 new file mode 100644 index 0000000..fcb4b25 --- /dev/null +++ b/src/division.cairo @@ -0,0 +1,3 @@ +pub fn div(x: i8, y: i8) -> i8 { + x / y +} diff --git a/src/kill_switch.cairo b/src/kill_switch.cairo new file mode 100644 index 0000000..ca11903 --- /dev/null +++ b/src/kill_switch.cairo @@ -0,0 +1,47 @@ +#[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 7c80cbf..9912d20 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -9,5 +9,5 @@ pub mod ownable_counter; pub mod ownable; pub mod addition; +pub mod kill_switch; pub mod aggregator; - diff --git a/src/multiplication.cairo b/src/multiplication.cairo new file mode 100644 index 0000000..3477169 --- /dev/null +++ b/src/multiplication.cairo @@ -0,0 +1,3 @@ +pub fn mult(x: u8, y: u8) -> u8 { + x * y +} \ No newline at end of file diff --git a/src/ownable.cairo b/src/ownable.cairo index a3e7b14..4939bdd 100644 --- a/src/ownable.cairo +++ b/src/ownable.cairo @@ -47,9 +47,11 @@ 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 + + diff --git a/src/subtraction.cairo b/src/subtraction.cairo new file mode 100644 index 0000000..31a1f42 --- /dev/null +++ b/src/subtraction.cairo @@ -0,0 +1,5 @@ + +// / * - +pub fn sub(x: u8, y: u8) -> u8 { + x - y +} \ No newline at end of file diff --git a/src/sum.cairo b/src/sum.cairo new file mode 100644 index 0000000..d01947e --- /dev/null +++ b/src/sum.cairo @@ -0,0 +1,3 @@ +pub fn sum_u8(x: u8, y: u8) -> u8 { + x + y +} \ No newline at end of file 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); +} + + +