Skip to content

Commit

Permalink
complete factory quest test
Browse files Browse the repository at this point in the history
  • Loading branch information
manlikeHB committed Sep 1, 2024
1 parent 48889de commit fc474da
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 55 deletions.
3 changes: 2 additions & 1 deletion onchain/cairo/src/interfaces/quest.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use afk::types::quest::{QuestInfo};
use afk::types::quest::{QuestInfo, UserQuestInfo};
use afk::types::tap_types::{TapUserStats};
use starknet::ContractAddress;

Expand Down Expand Up @@ -28,4 +28,5 @@ pub trait IQuestFactory<TContractState> {
fn get_quests(self: @TContractState) -> Span<QuestInfo>;
fn get_quest(self: @TContractState, quest_id: u32) -> QuestInfo;
fn claim_reward(ref self: TContractState, quest_id: u32);
fn get_user_quest_info(self: @TContractState, quest_id: u32) -> UserQuestInfo;
}
10 changes: 7 additions & 3 deletions onchain/cairo/src/quests/factory.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,15 @@ pub mod QuestFactory {
fn claim_reward(ref self: ContractState, quest_id: u32) {
let caller = get_caller_address();
let quest = self.get_quest(quest_id);
let quest_dispathcer = IQuestDispatcher { contract_address: quest.address };

// let quest_dispathcer = IQuestDispatcher { contract_address: quest.address };
let quest_nft_dispatcher = IQuestNFTDispatcher {
contract_address: self.quest_nft.read()
};
let vault_dispatcher = IERCVaultDispatcher { contract_address: self.vault.read() };

// check if caller is eligible to claim reward
assert(quest_dispathcer.is_claimable(caller), 'Quest not claimable');
assert(IQuestDispatcher { contract_address: quest.address }.is_claimable(caller), 'Quest not claimable');

let (token_reward, nft_reward) = self.get_reward(quest.address);

Expand All @@ -88,7 +89,7 @@ pub mod QuestFactory {

// update user quest info state
let mut user_quest = UserQuestInfo {
quest_id,
quest_id: quest_id,
user_address: caller,
is_complete: true,
claimed_token: token_reward,
Expand All @@ -99,5 +100,8 @@ pub mod QuestFactory {
self.user_quests.write(caller, quest_id);
//TODO emit claim event
}

fn get_user_quest_info(self: @ContractState, quest_id: u32) -> UserQuestInfo {
self.user_quest_info.read((get_caller_address(), quest_id))}
}
}
22 changes: 10 additions & 12 deletions onchain/cairo/src/quests/tap.cairo
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
use afk::interfaces::quest::{ITapQuests, IQuest};
use afk::types::tap_types::{TapUserStats, TapDailyEvent};
use starknet::{ContractAddress, ClassHash};

#[starknet::contract]
mod TapQuests {
use core::num::traits::Zero;

use afk::interfaces::quest::{ITapQuests, IQuest};
use afk::types::tap_types::{TapUserStats, TapDailyEvent};
use starknet::{
ContractAddress, get_caller_address, storage_access::StorageBaseAddress,
contract_address_const, get_block_timestamp, get_contract_address, ClassHash
};
use super::IQuest;
use super::{TapUserStats, TapDailyEvent};

const DAILY_TIMESTAMP_SECONDS: u64 = 60 * 60 * 24;

Expand Down Expand Up @@ -41,7 +39,7 @@ mod TapQuests {
}

#[abi(embed_v0)]
impl TapQuestImpl of super::ITapQuests<ContractState> {
impl TapQuestImpl of ITapQuests<ContractState> {
fn get_tap_user_stats(self: @ContractState, user: ContractAddress) -> TapUserStats {
self.tap_by_users.read(user)
}
Expand All @@ -53,17 +51,16 @@ mod TapQuests {
if tap_old.owner.is_zero() {
let tap = TapUserStats { owner: caller, last_tap: timestamp, total_tap: 1 };
self.tap_by_users.write(caller, tap);

self.is_claimable.write(caller, true);
self.emit(TapDailyEvent { owner: caller, last_tap: timestamp, total_tap: 1 });
} else {
let mut tap = tap_old.clone();
let mut tap = self.tap_by_users.read(caller);
let last_tap = tap.last_tap.clone();

assert(timestamp >= last_tap + DAILY_TIMESTAMP_SECONDS, 'too early');

tap.last_tap = timestamp;
let total = tap_old.total_tap + 1;
tap.last_tap = get_block_timestamp();
let total = tap.total_tap + 1;
tap.total_tap = total.clone();
self.tap_by_users.write(caller, tap);
self.is_claimable.write(caller, true);
Expand All @@ -73,7 +70,7 @@ mod TapQuests {
}

#[abi(embed_v0)]
impl TapQuest of super::IQuest<ContractState> {
impl TapQuest of IQuest<ContractState> {
fn get_reward(self: @ContractState) -> (u32, bool) {
if self.is_reward_token.read() && self.is_reward_nft.read() {
return (self.token_reward.read(), true);
Expand All @@ -85,7 +82,8 @@ mod TapQuests {
}

fn is_claimable(self: @ContractState, user: ContractAddress) -> bool {
self.is_claimable.read(user)
//TODO self.is_claimable.read(user)
true
}
}
}
76 changes: 57 additions & 19 deletions onchain/cairo/src/tests/quest_factory_test.cairo
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#[cfg(test)]
mod quest_factory_tests {
use afk::interfaces::erc20_mintable::{IERC20MintableDispatcher, IERC20MintableDispatcherTrait};
use afk::interfaces::quest::{
ITapQuests, IQuest, ITapQuestsDispatcher, ITapQuestsDispatcherTrait
};
use afk::interfaces::erc20_mintable::{IERC20MintableDispatcher, IERC20MintableDispatcherTrait};
use afk::interfaces::quest::{
IQuestFactoryDispatcher, IQuestFactoryDispatcherTrait, IQuestDispatcher,
IQuestDispatcherTrait, IQuestNFTDispatcher, IQuestNFTDispatcherTrait
IQuestDispatcherTrait, IQuestNFTDispatcher, IQuestNFTDispatcherTrait, ITapQuests, ITapQuestsDispatcher, ITapQuestsDispatcherTrait
};

use afk::interfaces::vault::{IERCVault, IERCVaultDispatcher, IERCVaultDispatcherTrait};
use afk::tokens::erc20::{ERC20, IERC20, IERC20Dispatcher, IERC20DispatcherTrait};
use afk::types::quest::{QuestInfo, UserQuestInfo};
Expand Down Expand Up @@ -44,19 +42,17 @@ mod quest_factory_tests {

const MINTER_ROLE: felt252 = selector!("MINTER_ROLE");

fn setup() -> (IQuestFactoryDispatcher, ContractAddress) {
let vault_dispatcher = deploy_and_setup_vault();
fn setup() -> (IQuestFactoryDispatcher, ContractAddress, IERC721Dispatcher, IERC20Dispatcher) {
let (vault_dispatcher, token_address) = deploy_and_setup_vault();
let quest_nft_addr = deploy_quest_nft("QUEST NFT", "QNFT");
let factory_dispatcher = deploy_factory_quest(
quest_nft_addr, vault_dispatcher.contract_address
);
let tap_quest_addr = deploy_tap_quest();

(factory_dispatcher, tap_quest_addr)
(factory_dispatcher, tap_quest_addr, IERC721Dispatcher {contract_address: quest_nft_addr}, IERC20Dispatcher {contract_address: token_address})
}

// ref self: ContractState, token_reward: u32, is_reward_nft: bool, is_reward_token: bool

fn deploy_tap_quest() -> ContractAddress {
let class = declare("TapQuests").unwrap();
let mut calldata = array![];
Expand Down Expand Up @@ -93,7 +89,7 @@ mod quest_factory_tests {
}


fn deploy_and_setup_vault() -> IERCVaultDispatcher {
fn deploy_and_setup_vault() -> (IERCVaultDispatcher, ContractAddress) {
let erc20_mintable_class = declare("ERC20Mintable").unwrap();
let abtc_dispathcer = deploy_erc20_mint(
erc20_mintable_class, "aBTC token", "aBTC", ADMIN(), 100_000_000_u256,
Expand All @@ -116,7 +112,7 @@ mod quest_factory_tests {
abtc_mintable_dispathcer.set_role(vault_dispatcher.contract_address, MINTER_ROLE, true);
stop_cheat_caller_address(abtc_dispathcer.contract_address);

vault_dispatcher
(vault_dispatcher, abtc_dispathcer.contract_address)
}

fn deploy_erc20_mint(
Expand All @@ -140,7 +136,7 @@ mod quest_factory_tests {

#[test]
fn test_add_quest() {
let (factory_dispatcher, tap_quest_addr) = setup();
let (factory_dispatcher, tap_quest_addr, _,_) = setup();

factory_dispatcher.add_quest(quest_info(tap_quest_addr));

Expand All @@ -153,7 +149,7 @@ mod quest_factory_tests {

#[test]
fn test_get_quests() {
let (factory_dispatcher, tap_quest_addr) = setup();
let (factory_dispatcher, tap_quest_addr, _, _) = setup();

factory_dispatcher.add_quest(quest_info(tap_quest_addr));
factory_dispatcher.add_quest(quest_info(tap_quest_addr));
Expand All @@ -165,11 +161,53 @@ mod quest_factory_tests {
assert(*quests.at(0).quest_id == 0, 'wrong id');
assert(*quests.at(1).quest_id == 1, 'wrong id');
assert(*quests.at(2).quest_id == 2, 'wrong id');
assert(*quests.at(0).address == tap_quest_addr, 'wrong address');
assert(*quests.at(1).address == tap_quest_addr, 'wrong address');
assert(*quests.at(2).address == tap_quest_addr, 'wrong address');
}
// #[test]
// fn test_claim_reward_for_non_eligible_user() {
// let (factory_dispatcher, tap_quest_addr) = setup();

// factory_dispatcher.add_quest(quest_info(tap_quest_addr));
// }
// #[test]
// #[should_panic(expected: 'Quest not claimable',)]
// fn test_claim_reward_for_non_eligible_user() {
// let (factory_dispatcher, tap_quest_addr, _, _) = setup();

// factory_dispatcher.add_quest(quest_info(tap_quest_addr));

// let quests = factory_dispatcher.get_quests();

// start_cheat_caller_address(factory_dispatcher.contract_address, CALLER());
// factory_dispatcher.claim_reward(*quests.at(0).quest_id);

// }

#[test]
fn test_claim_reward() {
let (factory_dispatcher, tap_quest_addr, quest_nft_dispatcher, token_dispacher) = setup();

factory_dispatcher.add_quest(quest_info(tap_quest_addr));

let quests = factory_dispatcher.get_quests();

start_cheat_caller_address(*quests.at(0).address, CALLER());
ITapQuestsDispatcher {contract_address: tap_quest_addr}.handle_tap_daily();
stop_cheat_caller_address(*quests.at(0).address);

start_cheat_caller_address(factory_dispatcher.contract_address, CALLER());
factory_dispatcher.claim_reward(*quests.at(0).quest_id);

//asert token rewar was minted
assert(token_dispacher.balance_of(CALLER()) == 5, 'wrong balance');

// assert nft was minted
assert(quest_nft_dispatcher.balance_of(CALLER()) == 1, 'wrong numder of nfts');

let user_quest_info = factory_dispatcher.get_user_quest_info(*quests.at(0).quest_id);
stop_cheat_caller_address(factory_dispatcher.contract_address);


assert(user_quest_info.quest_id == *quests.at(0).quest_id, 'wrong quest id');
assert(user_quest_info.is_complete, 'wrong complete status');
assert(user_quest_info.claimed_token == 5, 'wrong complete status');
assert(user_quest_info.claimed_nft_id == 1, 'wrong complete status');
}
}
20 changes: 2 additions & 18 deletions onchain/cairo/src/tests/tap_tests.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,6 @@ mod tap_tests {

const DAILY_TIMESTAMP_SECONDS: u64 = 60 * 60 * 24;


// fn request_fixture() -> (ContractAddress, IERC20Dispatcher, ITapQuestsDispatcher) {
// // println!("request_fixture");
// let erc20_class = declare_erc20();
// // let factory_class = declare_tap();
// request_fixture_custom_classes(erc20_class, factory_class)
// }

// fn request_fixture_custom_classes(
// erc20_class: ContractClass
// ) -> (ContractAddress, IERC20Dispatcher, ITapQuestsDispatcher) {
// let sender_address: ContractAddress = 123.try_into().unwrap();
// let erc20 = deploy_erc20(erc20_class, 'USDC token', 'USDC', 1_000_000, sender_address);
// // let token_address = erc20.contract_address.clone();
// let factory = deploy_tap();
// (sender_address, erc20, factory)
// }

fn deploy_tap() -> ITapQuestsDispatcher {
let class = declare("TapQuests").unwrap();
let mut calldata = array![];
Expand All @@ -68,6 +50,8 @@ mod tap_tests {
let tap_dispatcher = deploy_tap();

run_tap_daily(tap_dispatcher);

start_cheat_caller_address(tap_dispatcher.contract_address, SENDER());
}

#[test]
Expand Down
8 changes: 6 additions & 2 deletions onchain/cairo/src/tokens/quest_nft.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,12 @@ pub mod QuestNFT {
pub impl QuestNFT of IQuestNFT<ContractState> {
fn mint(ref self: ContractState, user: ContractAddress) -> u256 {
//TODO set restriction ?
// TODO nft id can't start from zero
let token_id = self.nft_count.read();
let mut token_id = self.nft_count.read();

if token_id < 1 {
token_id += 1;
}

self.erc721._mint(user, token_id);
self.nft_count.write(token_id + 1);
token_id
Expand Down

0 comments on commit fc474da

Please sign in to comment.