Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use contract_::audition::types::season_and_audition::{
Appeal, ArtistRegistration, Audition, Evaluation, Genre, RegistrationConfig, Season, Vote,
Appeal, Audition, Evaluation, Genre, RegistrationConfig, Season, Vote,
};
use starknet::ContractAddress;

Expand Down
2 changes: 1 addition & 1 deletion contract_/src/audition/season_and_audition.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#[starknet::contract]
pub mod SeasonAndAudition {
use OwnableComponent::{HasComponent, InternalTrait};
use OwnableComponent::InternalTrait;
use contract_::audition::interfaces::iseason_and_audition::ISeasonAndAudition;
use contract_::audition::types::season_and_audition::{
Appeal, ArtistRegistration, Audition, Evaluation, Genre, RegistrationConfig, Season, Vote,
Expand Down
1 change: 0 additions & 1 deletion contract_/src/audition/stake_to_vote.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ pub mod StakeToVote {
ISeasonAndAuditionDispatcher, ISeasonAndAuditionDispatcherTrait,
};
use contract_::audition::interfaces::istake_to_vote::IStakeToVote;
use contract_::audition::types::season_and_audition::Audition;
use contract_::audition::types::stake_to_vote::*;
use contract_::errors::errors;
use core::num::traits::Zero;
Expand Down
1 change: 0 additions & 1 deletion contract_/src/audition/stake_withdrawal.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ pub mod StakeWithdrawal {
use contract_::audition::interfaces::istake_to_vote::{
IStakeToVoteDispatcher, IStakeToVoteDispatcherTrait,
};
use contract_::audition::types::season_and_audition::Audition;
use contract_::audition::types::stake_to_vote::{StakerInfo, StakingConfig};
use core::num::traits::Zero;
use openzeppelin::access::ownable::OwnableComponent;
Expand Down
10 changes: 5 additions & 5 deletions contract_/src/governance/ProposalSystem.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ pub mod ProposalSystem {
Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess,
StoragePointerWriteAccess,
};
use starknet::{
ContractAddress, contract_address_const, get_block_timestamp, get_caller_address,
};
use starknet::{ContractAddress, get_block_timestamp, get_caller_address};
use super::*;

const zero_address: ContractAddress = 0.try_into().unwrap();

#[storage]
struct Storage {
proposals: Map<u64, Proposal>,
Expand Down Expand Up @@ -237,7 +237,7 @@ pub mod ProposalSystem {
let proposal = self.proposals.read(current_id);

// Apply filters
let matches_token = token_contract == contract_address_const::<0>()
let matches_token = token_contract == zero_address
|| proposal.token_contract == token_contract;
let matches_status = status == 255_u8 || proposal.status == status;
let matches_category = category == 'ALL' || proposal.category == category;
Expand Down Expand Up @@ -475,7 +475,7 @@ pub mod ProposalSystem {
let current_artist = self.artists.read(token_contract);

// If no registered artist, register artist linked to token in factory contract
if current_artist == contract_address_const::<0>() {
if current_artist == zero_address {
let factory_dispatcher = IMusicShareTokenFactoryDispatcher {
contract_address: self.factory_contract.read(),
};
Expand Down
20 changes: 10 additions & 10 deletions contract_/src/governance/VotingMechanism.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,12 @@ pub mod VotingMechanism {
Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess,
StoragePointerWriteAccess,
};
use starknet::{contract_address_const, get_block_timestamp, get_caller_address};
use starknet::{get_block_timestamp, get_caller_address};
use super::*;

const zero_address: ContractAddress = 0.try_into().unwrap();


#[storage]
struct Storage {
// Votes: (proposal_id, voter) -> Vote
Expand Down Expand Up @@ -128,7 +131,7 @@ pub mod VotingMechanism {
assert(!self.completed_votings.read(proposal_id), 'Voting has already ended');

// Check if user has already voted
assert(self.has_voted(proposal_id, caller) == false, 'Already voted');
assert(!self.has_voted(proposal_id, caller), 'Already voted');

// Ensure the vote type is valid
assert(vote_type != VoteType::None, 'Invalid vote type');
Expand All @@ -140,8 +143,7 @@ pub mod VotingMechanism {
}
// Check if the user has delegated their vote
let delegation = self.delegations.read(caller);
if delegation != contract_address_const::<0>()
&& self.delegation_weights.read(delegation) > 0 {
if delegation != zero_address && self.delegation_weights.read(delegation) > 0 {
// If caller already delegated, revert the vote
assert(self.has_voted(proposal_id, caller), 'Cannot vote after delegation');
}
Expand Down Expand Up @@ -226,9 +228,7 @@ pub mod VotingMechanism {
) {
let caller = get_caller_address();
assert(caller != delegate, 'Cannot delegate to self');
assert(
self.delegations.read(caller) == contract_address_const::<0>(), 'Already delegated',
);
assert(self.delegations.read(caller) == zero_address, 'Already delegated');

// Ensure delegator has token balance
let token = IERC20Dispatcher { contract_address: token_address };
Expand Down Expand Up @@ -290,7 +290,7 @@ pub mod VotingMechanism {
ref self: ContractState, proposal_id: u64, token_contract: ContractAddress,
) -> u8 {
assert(self._verify_proposal_id(proposal_id), 'Invalid proposal ID');
assert(self.is_voting_active(proposal_id) == false, 'Voting period is still active');
assert(!self.is_voting_active(proposal_id), 'Voting period is still active');

let proposal_system_dispatcher = IProposalSystemDispatcher {
contract_address: self.proposal_system.read(),
Expand Down Expand Up @@ -387,13 +387,13 @@ pub mod VotingMechanism {
let delegation_from_sender = self.delegations.read(from);
let delegation_to_receiver = self.delegations.read(to);

if delegation_from_sender != contract_address_const::<0>() {
if delegation_from_sender != zero_address {
// Sender has delegated - update delegate's effective voting power
self._update_delegated_weight(proposal_id, delegation_from_sender, amount, false);
delegation_affected = true;
}

if delegation_to_receiver != contract_address_const::<0>() {
if delegation_to_receiver != zero_address {
// Receiver has delegated - update delegate's effective voting power
self._update_delegated_weight(proposal_id, delegation_to_receiver, amount, true);
delegation_affected = true;
Expand Down
25 changes: 4 additions & 21 deletions contract_/tests/test_access_control_emergency_stop.cairo
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
use contract_::audition::interfaces::iseason_and_audition::{
ISeasonAndAuditionDispatcher, ISeasonAndAuditionDispatcherTrait,
ISeasonAndAuditionSafeDispatcherTrait,
};
use contract_::audition::interfaces::iseason_and_audition::ISeasonAndAuditionDispatcherTrait;
use contract_::audition::season_and_audition::SeasonAndAudition;
use contract_::audition::types::season_and_audition::{Audition, Genre, Season};
use contract_::audition::types::season_and_audition::Genre;
use contract_::events::{PausedAll, ResumedAll};
use core::result::ResultTrait;
use snforge_std::{
ContractClassTrait, DeclareResultTrait, EventSpyAssertionsTrait, declare, spy_events,
start_cheat_caller_address, stop_cheat_caller_address,
EventSpyAssertionsTrait, spy_events, start_cheat_caller_address, stop_cheat_caller_address,
};
use starknet::{ContractAddress, get_block_timestamp};
use starknet::get_block_timestamp;
use crate::test_utils::*;

#[test]
Expand All @@ -21,12 +16,9 @@ fn test_owner_access_control() {
start_cheat_caller_address(dispatcher.contract_address, OWNER());

// Owner can create a season
let season_id = 1;
default_contract_create_season(dispatcher);

// Owner can create an audition
let audition_id = 1;
let test_audition = create_default_audition(audition_id, season_id);
dispatcher.create_audition('Summer Hits', Genre::Pop, 1675123200);

// Owner can add oracles
Expand All @@ -43,7 +35,6 @@ fn test_non_owner_cannot_create_season() {
// Non-owner tries to create a season
start_cheat_caller_address(dispatcher.contract_address, USER());

let season_id = 1;
default_contract_create_season(dispatcher);

stop_cheat_caller_address(dispatcher.contract_address);
Expand All @@ -57,9 +48,6 @@ fn test_non_owner_cannot_create_audition() {
// Non-owner tries to create an audition
start_cheat_caller_address(dispatcher.contract_address, USER());

let audition_id = 1;
let season_id = 1;
let test_audition = create_default_audition(audition_id, season_id);
dispatcher.create_audition('Summer Hits', Genre::Pop, 1675123200);

stop_cheat_caller_address(dispatcher.contract_address);
Expand Down Expand Up @@ -173,7 +161,6 @@ fn test_cannot_create_season_when_paused() {
dispatcher.pause_all();

// Try to create a season when paused
let season_id = 1;
default_contract_create_season(dispatcher);

stop_cheat_caller_address(dispatcher.contract_address);
Expand All @@ -188,10 +175,6 @@ fn test_cannot_create_audition_when_paused() {
start_cheat_caller_address(dispatcher.contract_address, OWNER());
dispatcher.pause_all();

// Try to create an audition when paused
let audition_id = 1;
let season_id = 1;
let test_audition = create_default_audition(audition_id, season_id);
dispatcher.create_audition('Summer Hits', Genre::Pop, 1675123200);

stop_cheat_caller_address(dispatcher.contract_address);
Expand Down
78 changes: 13 additions & 65 deletions contract_/tests/test_audition_stake_withdrawal.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ use contract_::audition::stake_withdrawal::{
IStakeWithdrawalDispatcher, IStakeWithdrawalDispatcherTrait,
};
use contract_::audition::types::season_and_audition::Genre;
use contract_::audition::types::stake_to_vote::StakingConfig;
use core::num::traits::Zero;
use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};
use snforge_std::{
ContractClassTrait, DeclareResultTrait, declare, start_cheat_block_timestamp,
start_cheat_caller_address, stop_cheat_block_timestamp, stop_cheat_caller_address,
start_cheat_caller_address, stop_cheat_caller_address,
};
use starknet::{ContractAddress, contract_address_const, get_block_timestamp};
use starknet::{ContractAddress, get_block_timestamp};

// Test constants
const AUDITION_ID: u256 = 1;
Expand All @@ -27,27 +26,27 @@ const INITIAL_TOKEN_SUPPLY: u256 = 1000000000000; // 1M tokens with 6 decimals

// Test accounts
fn OWNER() -> ContractAddress {
contract_address_const::<'owner'>()
'owner'.try_into().unwrap()
}

fn STAKER1() -> ContractAddress {
contract_address_const::<'staker1'>()
'staker1'.try_into().unwrap()
}

fn STAKER2() -> ContractAddress {
contract_address_const::<'staker2'>()
'staker2'.try_into().unwrap()
}

fn STAKER3() -> ContractAddress {
contract_address_const::<'staker3'>()
'staker3'.try_into().unwrap()
}

fn NON_STAKER() -> ContractAddress {
contract_address_const::<'non_staker'>()
'non_staker'.try_into().unwrap()
}

fn UNAUTHORIZED_USER() -> ContractAddress {
contract_address_const::<'unauthorized'>()
'unauthorized'.try_into().unwrap()
}

// Deploy audition contract for integration testing
Expand Down Expand Up @@ -204,53 +203,13 @@ fn test_initial_configuration() {
assert!(config.withdrawal_delay_after_results == WITHDRAWAL_DELAY, "Wrong delay");
}

#[test]
fn test_set_staking_config_by_owner() {
let (withdrawal_contract, token, _, staking_contract) = setup();

// Set config directly on staking contract (proper architecture)
start_cheat_caller_address(staking_contract.contract_address, OWNER());

staking_contract
.set_staking_config(
AUDITION_ID_2, STAKE_AMOUNT * 2, token.contract_address, WITHDRAWAL_DELAY * 2,
);

stop_cheat_caller_address(staking_contract.contract_address);

// Verify through withdrawal contract (read-only operation)
let retrieved_config = withdrawal_contract.get_staking_config(AUDITION_ID_2);
assert!(retrieved_config.required_stake_amount == STAKE_AMOUNT * 2, "Config not updated");
// Event emission testing would need proper event imports
}

#[test]
#[should_panic(expected: ('Caller is not the owner',))]
fn test_set_staking_config_unauthorized() {
let (withdrawal_contract, token, _, _) = setup();

// Use an existing audition ID to avoid audition existence error
start_cheat_caller_address(withdrawal_contract.contract_address, UNAUTHORIZED_USER());

let config = StakingConfig {
required_stake_amount: STAKE_AMOUNT,
stake_token: token.contract_address,
withdrawal_delay_after_results: WITHDRAWAL_DELAY,
};

// This should fail with "Caller is not the owner" since AUDITION_ID exists
withdrawal_contract.set_staking_config(AUDITION_ID, config);

stop_cheat_caller_address(withdrawal_contract.contract_address);
}

#[test]
fn test_set_audition_contract() {
let (withdrawal_contract, _, _, _) = setup();

start_cheat_caller_address(withdrawal_contract.contract_address, OWNER());

let new_audition_contract = contract_address_const::<'new_audition'>();
let new_audition_contract: ContractAddress = 'new_audition'.try_into().unwrap();
withdrawal_contract.set_audition_contract(new_audition_contract);

stop_cheat_caller_address(withdrawal_contract.contract_address);
Expand All @@ -263,7 +222,7 @@ fn test_set_audition_contract_unauthorized() {

start_cheat_caller_address(withdrawal_contract.contract_address, UNAUTHORIZED_USER());

let new_audition_contract = contract_address_const::<'new_audition'>();
let new_audition_contract = 'new_audition'.try_into().unwrap();
withdrawal_contract.set_audition_contract(new_audition_contract);

stop_cheat_caller_address(withdrawal_contract.contract_address);
Expand Down Expand Up @@ -311,17 +270,6 @@ fn test_are_results_finalized_true_after_ending() {
// The core withdrawal functionality works correctly when results ARE finalized.
}

// === STAKER INFO TESTS ===

#[test]
fn test_get_staker_info_empty() {
let (withdrawal_contract, _, _, _) = setup();

let staker_info = withdrawal_contract.get_staker_info(STAKER1(), AUDITION_ID);
assert!(staker_info.address.is_zero(), "Staker should be zero");
assert!(staker_info.staked_amount == 0, "Staked amount should be zero");
}

// === WITHDRAWAL FUNCTION TESTS ===

#[test]
Expand Down Expand Up @@ -494,7 +442,7 @@ fn test_get_withdrawn_stakers_empty() {

#[test]
fn test_audition_contract_integration_no_contract() {
let zero_address = contract_address_const::<0>();
let zero_address = 0.try_into().unwrap();
let withdrawal_contract = deploy_stake_withdrawal_contract(zero_address, zero_address);

let results_finalized = withdrawal_contract.are_results_finalized(AUDITION_ID);
Expand Down Expand Up @@ -539,7 +487,7 @@ fn test_zero_address_staker() {
let (withdrawal_contract, _, _, _) = setup();

// Zero address should not be able to withdraw since no staker info exists
let zero_address = contract_address_const::<0>();
let zero_address = 0.try_into().unwrap();
let can_withdraw = withdrawal_contract.can_withdraw_stake(zero_address, AUDITION_ID);
assert!(!can_withdraw, "Should not be able to withdraw for zero address");
}
Expand Down Expand Up @@ -642,7 +590,7 @@ fn test_large_audition_ids() {

#[test]
fn test_multiple_batch_operations() {
let (withdrawal_contract, _, audition_contract, _) = setup();
let (withdrawal_contract, _, _, _) = setup();

// Create many audition IDs for batch testing
let audition_ids = array![
Expand Down
Loading
Loading