Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
scarb 2.11.4
starknet-foundry 0.40.0
2 changes: 1 addition & 1 deletion src/IHello.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ pub trait IHelloStarknet<TContractState> {
fn get_balance(self: @TContractState) -> felt252;

fn add_and_subtract(ref self: TContractState, amount: felt252);
}
}
2 changes: 1 addition & 1 deletion src/INumber.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ pub trait INumber<TContractState> {
fn set_number(ref self: TContractState, amount: u8);
/// Returns the current number
fn get_number(self: @TContractState) -> u8;
}
}
129 changes: 112 additions & 17 deletions src/aggregator.cairo
Original file line number Diff line number Diff line change
@@ -1,77 +1,172 @@
#[starknet::interface]
pub trait IAggregator<TContractState> {
/// Increase contract count.
// Increase contract count.
fn increase_count(ref self: TContractState, amount: u32);
/// Increase contract count.
///
// Increase counter count
fn increase_counter_count(ref self: TContractState, amount: u32);

/// Retrieve contract count.
// Retrieve contract count.
fn decrease_count_by_one(ref self: TContractState);
/// Retrieve contract count.
// Retrieve contract count.
fn get_count(self: @TContractState) -> u32;

// Activate the switch
fn activate_switch(ref self: TContractState);
}

/// Simple contract for managing count.
#[starknet::contract]
mod Agggregator {
pub mod Aggregator {
use cohort_4::counter::{ICounterDispatcher, ICounterDispatcherTrait};
use cohort_4::killswitch::{IKillSwitchDispatcher, IKillSwitchDispatcherTrait};
use starknet::ContractAddress;
use cohort_4::ownable::{IOwnableDispatcher, IOwnableDispatcherTrait};
use core::num::traits::Zero;
use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};

use starknet::{ContractAddress, get_caller_address};
use crate::events::*;
use super::*;

#[storage]
struct Storage {
count: u32,
counter: ContractAddress,
killswitch: ContractAddress,
ownable: ContractAddress,
}

#[derive(Drop, starknet::Event)]
pub struct CountIncreased {
pub new_count: u32,
pub caller: ContractAddress,
}

#[derive(Drop, starknet::Event)]
pub struct CounterCountIncreased {
pub new_counter: u32,
pub caller: ContractAddress,
}

#[derive(Drop, starknet::Event)]
pub struct CountDecreasedByOne {
pub new_count: u32,
pub caller: ContractAddress,
}

#[derive(Drop, starknet::Event)]
pub struct SwitchStatus {
pub status: bool,
pub caller: ContractAddress,
}


#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {
CountIncreased: CountIncreased,
CounterCountIncreased: CounterCountIncreased,
CountDecreasedByOne: CountDecreasedByOne,
SwitchStatus: SwitchStatus,
}

#[constructor]
fn constructor(ref self: ContractState, counter: ContractAddress, killswitch: ContractAddress) {
fn constructor(
ref self: ContractState,
counter: ContractAddress,
killswitch: ContractAddress,
ownable: ContractAddress,
) {
//Validate the addresses to be sure
self.validate_contract_addresses(counter, killswitch, ownable);

self.counter.write(counter);
self.killswitch.write(killswitch);
self.ownable.write(ownable);
}


#[abi(embed_v0)]
impl AggregatorImpl of super::IAggregator<ContractState> {
fn increase_count(ref self: ContractState, amount: u32) {
// Check ownership with internal function
self.assert_only_owner();
assert(amount > 0, 'Amount cannot be 0');

let counter = ICounterDispatcher { contract_address: self.counter.read() };
let counter_count = counter.get_count();
self.count.write(counter_count + amount);
let new_count = counter_count + amount;
self.count.write(new_count);

self.emit(CountIncreased { new_count: amount, caller: get_caller_address() });
}

fn increase_counter_count(ref self: ContractState, amount: u32) {
// Check ownership with internal function

self.assert_only_owner();

let killswitch: IKillSwitchDispatcher = IKillSwitchDispatcher {
contract_address: self.killswitch.read(),
};
assert(killswitch.get_status(), 'not active');
ICounterDispatcher { contract_address: self.counter.read() }.increase_count(amount)
assert(killswitch.get_status(), 'Oops! Switch is off');
ICounterDispatcher { contract_address: self.counter.read() }.increase_count(amount);
self.emit(CounterCountIncreased { new_counter: amount, caller: get_caller_address() });
}

fn decrease_count_by_one(ref self: ContractState) {
// Check ownership with internal function
self.assert_only_owner();

let current_count = self.get_count();
assert!(current_count != 0, "Amount cannot be 0");
self.count.write(current_count - 1);
assert(current_count != 0, 'Count cannot be 0');
let new_count1 = current_count - 1;
self.count.write(new_count1);

self.emit(CountDecreasedByOne { new_count: new_count1, caller: get_caller_address() });
}

fn activate_switch(ref self: ContractState) {
self.assert_only_owner();

let killswitch: IKillSwitchDispatcher = IKillSwitchDispatcher {
contract_address: self.killswitch.read(),
};

if !killswitch.get_status() {
killswitch.switch()
}

self.emit(SwitchStatus { status: true, caller: get_caller_address() });
}

fn get_count(self: @ContractState) -> u32 {
self.assert_only_owner();
self.count.read()
}
}

#[generate_trait]
impl OwnerHelpers of OwnersHelpersTrait {
//check owner is caller
fn assert_only_owner(self: @ContractState) {
let caller = get_caller_address();
// Dispatcher to interact with contract
let ownable = IOwnableDispatcher { contract_address: self.ownable.read() };
let owner = ownable.get_owner();
assert(caller == owner, 'Caller is not owner');
}

fn validate_contract_addresses(
self: @ContractState,
counter: ContractAddress,
killswitch: ContractAddress,
ownable: ContractAddress,
) {
//check that none is address zero
assert(counter.is_non_zero(), 'Counter address cannot be 0');
assert(killswitch.is_non_zero(), 'KillSwitch address cannot be 0');
assert(ownable.is_non_zero(), 'Ownable address cannot be 0');

//check there is no duplicate
assert(counter != killswitch, 'counter cant be killswitch');
assert(counter != ownable, 'counter cant be ownable');
assert(killswitch != ownable, 'killswitch cant be ownable');
}
}
}
2 changes: 1 addition & 1 deletion src/counter.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ mod Counter {
}

fn get_count(self: @ContractState) -> u32 {
self.count.read()
self.count.read()
}
}
}
6 changes: 3 additions & 3 deletions src/hello.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ mod HelloStarknet {
}

fn add_and_subtract(ref self: ContractState, amount: felt252) {
self._add(amount);
self._subtract(amount);
self._add(amount);
self._subtract(amount);
}
}

Expand All @@ -52,4 +52,4 @@ mod HelloStarknet {
number
}
}
}
}
1 change: 0 additions & 1 deletion src/killswitch.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ mod KillSwitch {
#[abi(embed_v0)]
impl KillSwitchImpl of super::IKillSwitch<ContractState> {
fn switch(ref self: ContractState) {
// assert(amount != 0, 'Amount cannot be 0');
self.status.write(!self.status.read());
}

Expand Down
59 changes: 3 additions & 56 deletions src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,61 +1,8 @@
pub mod hello;
pub mod IHello;
pub mod INumber;
pub mod aggregator;
pub mod counter;
pub mod hello;
pub mod killswitch;
pub mod aggregator;



fn main() {
// Function calls (Uncomment to execute them)
// say_name("Sylvia Nnoruka!");
// intro_to_felt();

let num_1 = 5;
let num_2 = 10;
let sum = sum_num(num_1, num_2);
println!("The sum of {} and {} is = {}", num_1, num_2, sum);

// check_u16(6553); // Uncomment if needed
is_greater_than_50(3);
}

// DATA TYPES IN CAIRO
// - felts: felt252 (Field elements)
// - ByteArray: Represents a sequence of bytes
// - Integers:
// - Signed: i8, i16, i32, i64, i128, i256
// - Unsigned: u8, u16, u32, u64, u128, u256
// - Boolean: bool

// Function to demonstrate ByteArray usage
fn say_name(x: ByteArray) {
println!("{}", x);
}

// Function to demonstrate felt252 usage
fn intro_to_felt() {
let x = 40000;
println!("{}", x);
}

// Function to sum two u8 integers
fn sum_num(x: u8, y: u8) -> u8 {
return x + y;
}

// Function to print a u16 integer
fn check_u16(x: u16) {
println!("{x}");
}
pub mod ownable;

// Function to check if a u32 integer is greater than 50
fn is_greater_than_50(x: u32) -> bool {
if x > 50 {
println!("true");
return true;
}
println!("false");
return false;
}
43 changes: 43 additions & 0 deletions src/ownable.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use starknet::ContractAddress;

#[starknet::interface]
pub trait IOwnable<TContractState> {
fn set_owner(ref self: TContractState, owner: ContractAddress);
fn get_owner(self: @TContractState) -> ContractAddress;
}

#[starknet::contract]
mod Ownable {
use core::num::traits::Zero;
use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};
use starknet::{ContractAddress, get_caller_address};


#[storage]
struct Storage {
owner: ContractAddress,
}


#[constructor]
fn constructor(ref self: ContractState, initial_owner: ContractAddress) {
assert(initial_owner.is_non_zero(), 'Owner cannot be zero address');
self.owner.write(initial_owner);
}

#[abi(embed_v0)]
impl OwnableImpl of super::IOwnable<ContractState> {
fn set_owner(ref self: ContractState, owner: ContractAddress) {
let caller = get_caller_address();
let current_owner = self.owner.read();
assert(current_owner == caller, 'Nope! only owner can call this');
assert(owner.is_non_zero(), 'New owner cant be zero address');
//Set the owner
self.owner.write(owner);
}

fn get_owner(self: @ContractState) -> ContractAddress {
self.owner.read()
}
}
}
Loading