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
80 changes: 80 additions & 0 deletions contracts/src/wager/types.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,83 @@ pub enum WagerState {
Resolved,
Cancelled
}

#[derive(Copy, Drop, Serde)]
pub struct Achievement {
pub achievement_type: AchievementType,
pub earned_at: u64,
pub wager_id: u64,
}

#[derive(Copy, Drop, Serde, PartialEq)]
pub enum AchievementType {
FirstWager, // Created first wager
FirstWin, // Won first wager
FirstJoin, // Joined first wager
WinStreak5, // 5 consecutive wins
WinStreak10, // 10 consecutive wins
AccuratePrediction, // 80%+ accuracy over 10 wagers
HighStaker, // Placed wager worth 1000+ STRK
FrequentPlayer, // Participated in 50+ wagers
WealthyWinner, // Won 10,000+ STRK total
QuickWinner, // Won within first 24 hours of wager creation
}

#[derive(Copy, Drop, Serde)]
pub struct UserStats {
pub total_wagers_created: u64,
pub total_wagers_joined: u64,
pub total_wins: u64,
pub total_losses: u64,
pub current_win_streak: u64,
pub best_win_streak: u64,
pub total_volume_wagered: u256,
pub total_winnings: u256,
pub accuracy_percentage: u64, // percentage (0-100)
}

impl AchievementTypeIntoFelt252 of Into<AchievementType, felt252> {
fn into(self: AchievementType) -> felt252 {
match self {
AchievementType::FirstWager => 'FIRSTWAGER',
AchievementType::FirstWin => 'FIRSTWIN',
AchievementType::FirstJoin => 'FIRSTJOIN',
AchievementType::WinStreak5 => 'WINSTREAK5',
AchievementType::WinStreak10 => 'WINSTREAK10',
AchievementType::AccuratePrediction => 'ACCURATEPREDICTION',
AchievementType::HighStaker => 'HIGHSTAKER',
AchievementType::FrequentPlayer => 'FREQUENTPLAYER',
AchievementType::WealthyWinner => 'WEALTHYWINNER',
AchievementType::QuickWinner => 'QUICKWINNER',
}
}
}

impl Felt252TryIntoAchievementType of TryInto<felt252, AchievementType> {
fn try_into(self: felt252) -> Option<AchievementType> {
if self == 'FIRSTWAGER' {
Option::Some(AchievementType::FirstWager)
} else if self == 'FIRSTWIN' {
Option::Some(AchievementType::FirstWin)
} else if self == 'FIRSTJOIN' {
Option::Some(AchievementType::FirstJoin)
} else if self == 'WINSTREAK5' {
Option::Some(AchievementType::WinStreak5)
} else if self == 'WINSTREAK10' {
Option::Some(AchievementType::WinStreak10)
} else if self == 'ACCURATEPREDICTION' {
Option::Some(AchievementType::AccuratePrediction)
} else if self == 'HIGHSTAKER' {
Option::Some(AchievementType::HighStaker)
} else if self == 'FREQUENTPLAYER' {
Option::Some(AchievementType::FrequentPlayer)
} else if self == 'WEALTHYWINNER' {
Option::Some(AchievementType::WealthyWinner)
} else if self == 'QUICKWINNER' {
Option::Some(AchievementType::QuickWinner)
} else {
Option::None
}
}
}

8 changes: 7 additions & 1 deletion contracts/src/wager/wager.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ pub mod StrkWager {
use starknet::get_block_timestamp;

use contracts::wager::interface::IStrkWager;
use contracts::wager::types::{Wager, Category, Mode, Claim, WagerState};
use contracts::wager::types::{
Wager, Category, Mode, Claim, WagerState, AchievementType, Achievement, UserStats
};
use openzeppelin::introspection::src5::SRC5Component;
use openzeppelin::access::accesscontrol::{AccessControlComponent};
use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};
Expand Down Expand Up @@ -50,6 +52,10 @@ pub mod StrkWager {
accesscontrol: AccessControlComponent::Storage,
#[substorage(v0)]
src5: SRC5Component::Storage,
// Reputation system storage
user_stats: Map<ContractAddress, UserStats>,
user_achievements: Map<ContractAddress, Map<AchievementType, Achievement>>,
user_achievement_count: Map<ContractAddress, u64>,
}

#[event]
Expand Down