Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add template quest contract and check is_claimable #61

Merged
80 changes: 80 additions & 0 deletions onchain/src/quests/template_quest.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use art_peace::templates::interfaces::{
ITemplateStoreDispatcher, ITemplateStoreDispatcherTrait, ITemplateVerifierDispatcher,
ITemplateVerifierDispatcherTrait, TemplateMetadata
};

#[starknet::contract]
pub mod TemplateQuest {
use starknet::{ContractAddress, get_caller_address};
use art_peace::{IArtPeaceDispatcher, IArtPeaceDispatcherTrait};
use art_peace::quests::{IQuest, QuestClaimed};

#[storage]
struct Storage {
art_peace: IArtPeaceDispatcher,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to store this as a ContractAddress and have a separate storage slot for ITemplateStoreDispatcher since you won't be using the IArtPeaceDispatcher for anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean having art_peace: ContractAddress ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's right

reward: u32,
claimed: LegacyMap<ContractAddress, bool>,
template_store: ITemplateStoreDispatcher
}

#[derive(Drop, Serde)]
pub struct TemplateQuestInitParams {
pub art_peace: ContractAddress,
pub reward: u32,
pub template_store: ContractAddress
mubarak23 marked this conversation as resolved.
Show resolved Hide resolved
}

#[constructor]
fn constructor(ref self: ContractState, init_params: TemplateQuestInitParams,) {
self.art_peace.write(IArtPeaceDispatcher { contract_address: init_params.art_peace });
self.reward.write(init_params.reward);
self
.template_store
.write(ITemplateStoreDispatcher { contract_address: init_params.template_store });
}
b-j-roberts marked this conversation as resolved.
Show resolved Hide resolved


#[abi(embed_v0)]
impl TemplateQuest of IQuest<ContractState> {
fn get_reward(self: @ContractState) -> u32 {
self.reward.read()
}

fn is_claimable(
self: @ContractState, user: ContractAddress, calldata: Span<felt252>
) -> bool {
let art_peace = self.art_peace.read();

if self.claimed.read(user) {
return false;
}

let template_id = calldata[0];

let template = self.template_store.get_template(template_id);

if template.creator != user {
return false;
}

return true;
}

fn claim(ref self: ContractState, user: ContractAddress, calldata: Span<felt252>) -> u32 {
assert(
get_caller_address() == self.art_peace.read().contract_address,
'Only ArtPeace can claim quests'
);
// TODO: should we revert if the quest is not claimable?
if !self.is_claimable(user, calldata) {
return 0;
}

self.claimed.write(user, true);
let reward = self.reward.read();
self.emit(QuestClaimed { user, reward, calldata });

reward
}
}
}
3 changes: 2 additions & 1 deletion onchain/src/templates/interfaces.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ pub struct TemplateMetadata {
pub width: u128,
pub height: u128,
pub reward: u256,
pub reward_token: ContractAddress
pub reward_token: ContractAddress,
pub creator: ContractAddress
}

#[starknet::interface]
Expand Down
11 changes: 9 additions & 2 deletions onchain/src/tests/art_peace.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use openzeppelin::token::erc721::interface::{IERC721Dispatcher, IERC721Dispatche
use snforge_std as snf;
use snforge_std::{CheatTarget, ContractClassTrait};

use starknet::{ContractAddress, contract_address_const, get_contract_address};
use starknet::{ContractAddress, contract_address_const, get_contract_address, get_caller_address};

const DAY_IN_SECONDS: u64 = consteval_int!(60 * 60 * 24);
const WIDTH: u128 = 100;
Expand Down Expand Up @@ -402,7 +402,13 @@ fn template_full_basic_test() {
let template_image = array![1, 2, 3, 4];
let template_hash = compute_template_hash(template_image.span());
let template_metadata = TemplateMetadata {
hash: template_hash, position: 0, width: 2, height: 2, reward: 0, reward_token: erc20_mock,
hash: template_hash,
position: 0,
width: 2,
height: 2,
reward: 0,
reward_token: erc20_mock,
creator: get_caller_address()
};

template_store.add_template(template_metadata);
Expand Down Expand Up @@ -550,6 +556,7 @@ fn deposit_reward_test() {
height: 2,
reward: reward_amount,
reward_token: erc20_mock,
creator: get_caller_address(),
};

IERC20Dispatcher { contract_address: erc20_mock }.approve(art_peace_address, reward_amount);
Expand Down