Skip to content

Commit

Permalink
remove Status
Browse files Browse the repository at this point in the history
  • Loading branch information
Nenad committed Jun 14, 2024
1 parent 30c7034 commit 999fed6
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 111 deletions.
4 changes: 2 additions & 2 deletions listings/applications/advanced_factory/src/tests.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use snforge_std::{

// Define a goal contract to deploy
use crowdfunding::campaign::{Campaign, ICampaignDispatcher, ICampaignDispatcherTrait};
use crowdfunding::campaign::Status;
use components::ownable::{IOwnableDispatcher, IOwnableDispatcherTrait};


Expand Down Expand Up @@ -78,7 +77,8 @@ fn test_create_campaign() {
assert_eq!(details.goal, goal);
assert_eq!(details.start_time, start_time);
assert_eq!(details.end_time, end_time);
assert_eq!(details.status, Status::ACTIVE);
assert_eq!(details.claimed, false);
assert_eq!(details.canceled, false);
assert_eq!(details.token, token);
assert_eq!(details.total_pledges, 0);
assert_eq!(details.creator, campaign_creator);
Expand Down
71 changes: 29 additions & 42 deletions listings/applications/crowdfunding/src/campaign.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@ pub mod pledges;
// ANCHOR: contract
use starknet::{ClassHash, ContractAddress};

#[derive(Drop, Debug, Serde, PartialEq, starknet::Store)]
pub enum Status {
ACTIVE,
CANCELED,
SUCCESSFUL,
FAILED,
}

#[derive(Drop, Serde)]
pub struct Details {
pub creator: ContractAddress,
Expand All @@ -19,7 +11,8 @@ pub struct Details {
pub start_time: u64,
pub end_time: u64,
pub description: ByteArray,
pub status: Status,
pub claimed: bool,
pub canceled: bool,
pub token: ContractAddress,
pub total_pledges: u256,
}
Expand Down Expand Up @@ -48,7 +41,7 @@ pub mod Campaign {
};
use components::ownable::ownable_component;
use super::pledges::pledgeable_component;
use super::{Details, Status};
use super::{Details};

component!(path: ownable_component, storage: ownable, event: OwnableEvent);
component!(path: pledgeable_component, storage: pledges, event: PledgeableEvent);
Expand All @@ -73,7 +66,8 @@ pub mod Campaign {
title: ByteArray,
description: ByteArray,
total_pledges: u256,
status: Status
claimed: bool,
canceled: bool,
}

#[event]
Expand All @@ -95,7 +89,6 @@ pub mod Campaign {
#[derive(Drop, starknet::Event)]
pub struct Canceled {
pub reason: ByteArray,
pub status: Status,
}

#[derive(Drop, starknet::Event)]
Expand Down Expand Up @@ -142,6 +135,7 @@ pub mod Campaign {
pub mod Errors {
pub const NOT_CREATOR: felt252 = 'Not creator';
pub const ENDED: felt252 = 'Campaign already ended';
pub const CLAIMED: felt252 = 'Campaign already claimed';
pub const NOT_STARTED: felt252 = 'Campaign not started';
pub const STILL_ACTIVE: felt252 = 'Campaign not ended';
pub const CANCELED: felt252 = 'Campaign canceled';
Expand Down Expand Up @@ -190,7 +184,6 @@ pub mod Campaign {
self.description.write(description);
self.creator.write(creator);
self.ownable._init(get_caller_address());
self.status.write(Status::ACTIVE);
self.start_time.write(start_time);
self.end_time.write(end_time);
self.token.write(IERC20Dispatcher { contract_address: token_address });
Expand All @@ -200,33 +193,29 @@ pub mod Campaign {
impl Campaign of super::ICampaign<ContractState> {
fn cancel(ref self: ContractState, reason: ByteArray) {
self._assert_only_creator();
assert(self.status.read() == Status::ACTIVE, Errors::ENDED);
assert(!self.canceled.read(), Errors::CANCELED);
assert(!self.claimed.read(), Errors::CLAIMED);

if !self._is_goal_reached() && self._is_expired() {
self.status.write(Status::FAILED);
} else {
self.status.write(Status::CANCELED);
}
self.canceled.write(true);

self._refund_all(reason.clone());
let status = self.status.read();

self.emit(Event::Canceled(Canceled { reason, status }));
self.emit(Event::Canceled(Canceled { reason }));
}

fn claim(ref self: ContractState) {
self._assert_only_creator();
self._assert_active();
assert(self._is_expired(), Errors::STILL_ACTIVE);
assert(self._is_started(), Errors::NOT_STARTED);
assert(self._is_ended(), Errors::STILL_ACTIVE);
assert(self._is_goal_reached(), Errors::TARGET_NOT_REACHED);
assert(!self.claimed.read(), Errors::CLAIMED);

let this = get_contract_address();
let token = self.token.read();

let amount = token.balance_of(this);
assert(amount > 0, Errors::ZERO_FUNDS);

self.status.write(Status::SUCCESSFUL);
self.claimed.write(true);

// no need to reset the pledges, as the campaign has ended
// and the data can be used as a testament to how much was raised
Expand All @@ -246,7 +235,8 @@ pub mod Campaign {
goal: self.goal.read(),
start_time: self.start_time.read(),
end_time: self.end_time.read(),
status: self.status.read(),
claimed: self.claimed.read(),
canceled: self.canceled.read(),
token: self.token.read().contract_address,
total_pledges: self.total_pledges.read(),
}
Expand All @@ -261,8 +251,9 @@ pub mod Campaign {
}

fn pledge(ref self: ContractState, amount: u256) {
self._assert_active();
assert(!self._is_expired(), Errors::ENDED);
assert(self._is_started(), Errors::NOT_STARTED);
assert(!self._is_ended(), Errors::ENDED);
assert(!self.canceled.read(), Errors::CANCELED);
assert(amount > 0, Errors::ZERO_DONATION);

let pledger = get_caller_address();
Expand All @@ -278,7 +269,9 @@ pub mod Campaign {

fn refund(ref self: ContractState, pledger: ContractAddress, reason: ByteArray) {
self._assert_only_creator();
self._assert_active();
assert(self._is_started(), Errors::NOT_STARTED);
assert(!self.claimed.read(), Errors::CLAIMED);
assert(!self.canceled.read(), Errors::CANCELED);
assert(pledger.is_non_zero(), Errors::ZERO_ADDRESS_PLEDGER);
assert(self.pledges.get(pledger) != 0, Errors::NOTHING_TO_REFUND);

Expand All @@ -288,7 +281,7 @@ pub mod Campaign {
}

fn unpledge(ref self: ContractState, reason: ByteArray) {
self._assert_active();
assert(self._is_started(), Errors::NOT_STARTED);
assert(!self._is_goal_reached(), Errors::TARGET_ALREADY_REACHED);
assert(self.pledges.get(get_caller_address()) != 0, Errors::NOTHING_TO_UNPLEDGE);

Expand All @@ -302,8 +295,8 @@ pub mod Campaign {
self.ownable._assert_only_owner();
assert(impl_hash.is_non_zero(), Errors::CLASS_HASH_ZERO);

// only active campaigns have funds to refund and duration to update
if get_block_timestamp() >= self.start_time.read() {
// only active campaigns have funds to refund and an end time to update
if self._is_started() {
if let Option::Some(end_time) = new_end_time {
assert(end_time >= get_block_timestamp(), Errors::END_BEFORE_NOW);
assert(
Expand All @@ -328,27 +321,21 @@ pub mod Campaign {
assert(caller == self.creator.read(), Errors::NOT_CREATOR);
}

fn _assert_active(self: @ContractState) {
assert(get_block_timestamp() >= self.start_time.read(), Errors::NOT_STARTED);
assert(self.status.read() == Status::ACTIVE, Errors::ENDED);
fn _is_started(self: @ContractState) -> bool {
get_block_timestamp() >= self.start_time.read()
}

fn _is_expired(self: @ContractState) -> bool {
fn _is_ended(self: @ContractState) -> bool {
get_block_timestamp() >= self.end_time.read()
}

fn _is_goal_reached(self: @ContractState) -> bool {
self.total_pledges.read() >= self.goal.read()
}

fn _refund(ref self: ContractState, pledger: ContractAddress) -> u256 {
let amount = self.pledges.remove(pledger);

// if the campaign is "failed", then there's no need to set total_pledges to 0, as
// the campaign has ended and the field can be used as a testament to how much was raised
if self.status.read() == Status::ACTIVE {
self.total_pledges.write(self.total_pledges.read() - amount);
}
self.total_pledges.write(self.total_pledges.read() - amount);

let success = self.token.read().transfer(pledger, amount);
assert(success, Errors::TRANSFER_FAILED);
Expand Down
60 changes: 27 additions & 33 deletions listings/applications/crowdfunding/src/mock_upgrade.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub mod MockUpgrade {
};
use components::ownable::ownable_component;
use crowdfunding::campaign::pledges::pledgeable_component;
use crowdfunding::campaign::{ICampaign, Details, Status, Campaign::Errors};
use crowdfunding::campaign::{ICampaign, Details, Campaign::Errors};

component!(path: ownable_component, storage: ownable, event: OwnableEvent);
component!(path: pledgeable_component, storage: pledges, event: PledgeableEvent);
Expand All @@ -34,7 +34,8 @@ pub mod MockUpgrade {
title: ByteArray,
description: ByteArray,
total_pledges: u256,
status: Status
claimed: bool,
canceled: bool,
}

#[event]
Expand All @@ -56,7 +57,6 @@ pub mod MockUpgrade {
#[derive(Drop, starknet::Event)]
pub struct Canceled {
pub reason: ByteArray,
pub status: Status,
}

#[derive(Drop, starknet::Event)]
Expand Down Expand Up @@ -125,7 +125,6 @@ pub mod MockUpgrade {
self.description.write(description);
self.creator.write(creator);
self.ownable._init(get_caller_address());
self.status.write(Status::ACTIVE);
self.start_time.write(start_time);
self.end_time.write(end_time);
self.token.write(IERC20Dispatcher { contract_address: token_address });
Expand All @@ -135,33 +134,29 @@ pub mod MockUpgrade {
impl MockUpgrade of ICampaign<ContractState> {
fn cancel(ref self: ContractState, reason: ByteArray) {
self._assert_only_creator();
assert(self.status.read() == Status::ACTIVE, Errors::ENDED);
assert(!self.canceled.read(), Errors::CANCELED);
assert(!self.claimed.read(), Errors::CLAIMED);

if !self._is_goal_reached() && self._is_expired() {
self.status.write(Status::FAILED);
} else {
self.status.write(Status::CANCELED);
}
self.canceled.write(true);

self._refund_all(reason.clone());
let status = self.status.read();

self.emit(Event::Canceled(Canceled { reason, status }));
self.emit(Event::Canceled(Canceled { reason }));
}

fn claim(ref self: ContractState) {
self._assert_only_creator();
self._assert_active();
assert(self._is_expired(), Errors::STILL_ACTIVE);
assert(self._is_started(), Errors::NOT_STARTED);
assert(self._is_ended(), Errors::STILL_ACTIVE);
assert(self._is_goal_reached(), Errors::TARGET_NOT_REACHED);
assert(!self.claimed.read(), Errors::CLAIMED);

let this = get_contract_address();
let token = self.token.read();

let amount = token.balance_of(this);
assert(amount > 0, Errors::ZERO_FUNDS);

self.status.write(Status::SUCCESSFUL);
self.claimed.write(true);

// no need to reset the pledges, as the campaign has ended
// and the data can be used as a testament to how much was raised
Expand All @@ -181,7 +176,8 @@ pub mod MockUpgrade {
goal: self.goal.read(),
start_time: self.start_time.read(),
end_time: self.end_time.read(),
status: self.status.read(),
claimed: self.claimed.read(),
canceled: self.canceled.read(),
token: self.token.read().contract_address,
total_pledges: self.total_pledges.read(),
}
Expand All @@ -196,8 +192,9 @@ pub mod MockUpgrade {
}

fn pledge(ref self: ContractState, amount: u256) {
self._assert_active();
assert(!self._is_expired(), Errors::ENDED);
assert(self._is_started(), Errors::NOT_STARTED);
assert(!self._is_ended(), Errors::ENDED);
assert(!self.canceled.read(), Errors::CANCELED);
assert(amount > 0, Errors::ZERO_DONATION);

let pledger = get_caller_address();
Expand All @@ -213,7 +210,9 @@ pub mod MockUpgrade {

fn refund(ref self: ContractState, pledger: ContractAddress, reason: ByteArray) {
self._assert_only_creator();
self._assert_active();
assert(self._is_started(), Errors::NOT_STARTED);
assert(!self.claimed.read(), Errors::CLAIMED);
assert(!self.canceled.read(), Errors::CANCELED);
assert(pledger.is_non_zero(), Errors::ZERO_ADDRESS_PLEDGER);
assert(self.pledges.get(pledger) != 0, Errors::NOTHING_TO_REFUND);

Expand All @@ -223,7 +222,7 @@ pub mod MockUpgrade {
}

fn unpledge(ref self: ContractState, reason: ByteArray) {
self._assert_active();
assert(self._is_started(), Errors::NOT_STARTED);
assert(!self._is_goal_reached(), Errors::TARGET_ALREADY_REACHED);
assert(self.pledges.get(get_caller_address()) != 0, Errors::NOTHING_TO_UNPLEDGE);

Expand All @@ -237,8 +236,8 @@ pub mod MockUpgrade {
self.ownable._assert_only_owner();
assert(impl_hash.is_non_zero(), Errors::CLASS_HASH_ZERO);

// only active campaigns have funds to refund and duration to update
if self.status.read() == Status::ACTIVE {
// only active campaigns have funds to refund and an end time to update
if self._is_started() {
if let Option::Some(end_time) = new_end_time {
assert(end_time >= get_block_timestamp(), Errors::END_BEFORE_NOW);
assert(
Expand All @@ -263,27 +262,21 @@ pub mod MockUpgrade {
assert(caller == self.creator.read(), Errors::NOT_CREATOR);
}

fn _assert_active(self: @ContractState) {
assert(get_block_timestamp() >= self.start_time.read(), Errors::NOT_STARTED);
assert(self.status.read() == Status::ACTIVE, Errors::ENDED);
fn _is_started(self: @ContractState) -> bool {
get_block_timestamp() >= self.start_time.read()
}

fn _is_expired(self: @ContractState) -> bool {
fn _is_ended(self: @ContractState) -> bool {
get_block_timestamp() >= self.end_time.read()
}

fn _is_goal_reached(self: @ContractState) -> bool {
self.total_pledges.read() >= self.goal.read()
}

fn _refund(ref self: ContractState, pledger: ContractAddress) -> u256 {
let amount = self.pledges.remove(pledger);

// if the campaign is "failed", then there's no need to set total_pledges to 0, as
// the campaign has ended and the field can be used as a testament to how much was raised
if self.status.read() == Status::ACTIVE {
self.total_pledges.write(self.total_pledges.read() - amount);
}
self.total_pledges.write(self.total_pledges.read() - amount);

let success = self.token.read().transfer(pledger, amount);
assert(success, Errors::TRANSFER_FAILED);
Expand All @@ -300,3 +293,4 @@ pub mod MockUpgrade {
}
}
}

Loading

0 comments on commit 999fed6

Please sign in to comment.