Skip to content

Commit

Permalink
Few improvements (#33)
Browse files Browse the repository at this point in the history
* few improvements

* Docker snfoundry version

---------

Co-authored-by: Brandon Roberts <[email protected]>
  • Loading branch information
TAdev0 and b-j-roberts authored Apr 11, 2024
1 parent 5d71f79 commit 5c14814
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
scarb 2.6.3
starknet-foundry 0.20.0
starknet-foundry 0.21.0
2 changes: 1 addition & 1 deletion backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/instal
RUN curl -L https://raw.githubusercontent.com/foundry-rs/starknet-foundry/master/scripts/install.sh | bash
# TODO: Source not working properly & requiring manual /root/.local/bin/ paths
RUN source /root/.profile
RUN /bin/bash /root/.local/bin/snfoundryup --version 0.20.0
RUN /bin/bash /root/.local/bin/snfoundryup --version 0.21.0

# Copy over the configs
WORKDIR /configs
Expand Down
2 changes: 1 addition & 1 deletion onchain/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/instal
RUN curl -L https://raw.githubusercontent.com/foundry-rs/starknet-foundry/master/scripts/install.sh | bash
# TODO: Source not working properly & requiring manual /root/.local/bin/ paths
RUN source /root/.bashrc
RUN /bin/bash /root/.local/bin/snfoundryup --version 0.20.0
RUN /bin/bash /root/.local/bin/snfoundryup --version 0.21.0

# TODO: build container?

Expand Down
4 changes: 2 additions & 2 deletions onchain/Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ dependencies = [

[[package]]
name = "snforge_std"
version = "0.20.0"
source = "git+https://github.com/foundry-rs/starknet-foundry?tag=v0.20.0#423eecf7847469e353258321274394b9155d24eb"
version = "0.21.0"
source = "git+https://github.com/foundry-rs/starknet-foundry?tag=v0.21.0#2996b8c1dd66b2715fc67e69578089f278a46790"
3 changes: 2 additions & 1 deletion onchain/Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
[package]
name = "art_peace"
version = "0.1.0"
edition = "2023_11"

# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html

[dependencies]
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.20.0" }
snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry", tag = "v0.21.0" }
starknet = "2.6.3"

[scripts]
Expand Down
39 changes: 23 additions & 16 deletions onchain/src/art_peace.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
pub mod ArtPeace {
use starknet::ContractAddress;
use art_peace::{IArtPeace, Pixel};
use art_peace::quests::{IQuestDispatcher, IQuestDispatcherTrait};
use art_peace::quests::interfaces::{IQuestDispatcher, IQuestDispatcherTrait};
use art_peace::templates::component::TemplateStoreComponent;
use art_peace::templates::{ITemplateVerifier, TemplateMetadata};
use art_peace::templates::interface::{ITemplateVerifier, TemplateMetadata};

component!(path: TemplateStoreComponent, storage: templates, event: TemplateEvent);

Expand Down Expand Up @@ -139,6 +139,7 @@ pub mod ArtPeace {

fn get_pixel_xy(self: @ContractState, x: u128, y: u128) -> Pixel {
let pos = x + y * self.canvas_width.read();

self.canvas.read(pos)
}

Expand All @@ -156,13 +157,13 @@ pub mod ArtPeace {

fn place_pixel(ref self: ContractState, pos: u128, color: u8) {
let now = starknet::get_block_timestamp();
assert!(now <= self.end_time.read());
assert!(pos < self.total_pixels.read());
assert!(color < self.color_count.read());
assert(now <= self.end_time.read(), '');
assert(pos < self.total_pixels.read(), '');
assert(color < self.color_count.read(), '');
// TODO: Use sender not caller?
let caller = starknet::get_caller_address();
// TODO: Only if the user has placed a pixel before?
assert!(now - self.last_placed_time.read(caller) >= self.time_between_pixels.read());
assert(now - self.last_placed_time.read(caller) >= self.time_between_pixels.read(), '');
let pixel = Pixel { color, owner: caller };
self.canvas.write(pos, pixel);
self.last_placed_time.write(caller, now);
Expand All @@ -182,21 +183,21 @@ pub mod ArtPeace {

fn place_extra_pixels(ref self: ContractState, positions: Array<u128>, colors: Array<u8>) {
let now = starknet::get_block_timestamp();
assert!(now <= self.end_time.read());
assert(now <= self.end_time.read(), '');
let pixel_count = positions.len();
assert!(pixel_count == colors.len());
assert(pixel_count == colors.len(), '');
let caller = starknet::get_caller_address();
let extra_pixels = self.extra_pixels.read(caller);
assert!(pixel_count <= extra_pixels);
assert(pixel_count <= extra_pixels, '');
let color_palette_count = self.color_count.read();
let total_pixels = self.total_pixels.read();
let day = self.day_index.read();
let mut i = 0;
while i < pixel_count {
let pos = *positions.at(i);
let color = *colors.at(i);
assert!(pos < total_pixels);
assert!(color < color_palette_count);
assert(pos < total_pixels, '');
assert(color < color_palette_count, '');
let pixel = Pixel { color, owner: caller };
self.canvas.write(pos, pixel);
self
Expand Down Expand Up @@ -242,6 +243,7 @@ pub mod ArtPeace {
colors.append(self.color_palette.read(i));
i += 1;
};

colors
}

Expand Down Expand Up @@ -285,6 +287,7 @@ pub mod ArtPeace {
quests.append(self.daily_quests.read((day_index, i)));
i += 1;
};

quests.span()
}

Expand All @@ -297,6 +300,7 @@ pub mod ArtPeace {
quests.append(self.daily_quests.read((day, i)));
i += 1;
};

quests.span()
}

Expand All @@ -316,14 +320,15 @@ pub mod ArtPeace {
quests.append(self.main_quests.read(i));
i += 1;
};

quests.span()
}

fn claim_daily_quest(
ref self: ContractState, day_index: u32, quest_id: u32, calldata: Span<felt252>
) {
let now = starknet::get_block_timestamp();
assert!(now <= self.end_time.read());
assert(now <= self.end_time.read(), '');
// TODO: Only allow to claim the quest of the current day
let quest = self.daily_quests.read((day_index, quest_id));
let user = starknet::get_caller_address();
Expand All @@ -340,7 +345,7 @@ pub mod ArtPeace {

fn claim_today_quest(ref self: ContractState, quest_id: u32, calldata: Span<felt252>) {
let now = starknet::get_block_timestamp();
assert!(now <= self.end_time.read());
assert(now <= self.end_time.read(), '');
let quest = self.daily_quests.read((self.day_index.read(), quest_id));
let user = starknet::get_caller_address();
let reward = IQuestDispatcher { contract_address: quest }.claim(user, calldata);
Expand All @@ -356,7 +361,7 @@ pub mod ArtPeace {

fn claim_main_quest(ref self: ContractState, quest_id: u32, calldata: Span<felt252>) {
let now = starknet::get_block_timestamp();
assert!(now <= self.end_time.read());
assert(now <= self.end_time.read(), '');
let quest = self.main_quests.read(quest_id);
let user = starknet::get_caller_address();
let reward = IQuestDispatcher { contract_address: quest }.claim(user, calldata);
Expand All @@ -383,6 +388,7 @@ pub mod ArtPeace {
};
i += 1;
};

total
}

Expand All @@ -396,6 +402,7 @@ pub mod ArtPeace {
total += self.user_pixels_placed.read((day, user, i));
i += 1;
};

total
}

Expand All @@ -410,8 +417,8 @@ pub mod ArtPeace {
impl ArtPeaceTemplateVerifier of ITemplateVerifier<ContractState> {
// TODO: Check template function
fn complete_template(ref self: ContractState, template_id: u32, template_image: Span<u8>) {
assert!(template_id < self.get_templates_count());
assert!(!self.is_template_complete(template_id));
assert(template_id < self.get_templates_count(), '');
assert(!self.is_template_complete(template_id), '');
// TODO: ensure template_image matches the template size & hash
let template_metadata: TemplateMetadata = self.get_template(template_id);
let non_zero_width: core::zeroable::NonZero::<u128> = template_metadata
Expand Down
4 changes: 2 additions & 2 deletions onchain/src/interface.cairo
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#[derive(Drop, Serde, starknet::Store)]
pub struct Pixel {
// Color index in the palette
color: u8,
pub color: u8,
// The person that placed the pixel
owner: starknet::ContractAddress,
pub owner: starknet::ContractAddress,
}

// TODO: Tests for all
Expand Down
8 changes: 4 additions & 4 deletions onchain/src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ use art_peace::ArtPeace;
use interface::{IArtPeace, IArtPeaceDispatcher, IArtPeaceDispatcherTrait, Pixel};

mod quests {
pub mod interface;
mod pixel_quest;
pub mod interfaces;
pub mod pixel_quest;

use interface::{IQuest, QuestClaimed, IQuestDispatcher, IQuestDispatcherTrait};
use interfaces::{IQuest, IPixelQuest, QuestClaimed, IQuestDispatcher, IQuestDispatcherTrait};
}

mod templates {
pub mod interface;
mod component;
pub mod component;

use interface::{
TemplateMetadata, ITemplateVerifier, ITemplateStoreDispatcher,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,11 @@ pub trait IQuest<TContractState> {
// Claim the quest.
fn claim(ref self: TContractState, user: ContractAddress, calldata: Span<felt252>) -> u32;
}

#[starknet::interface]
pub trait IPixelQuest<TContractState> {
fn is_claimed(self: @TContractState, user: starknet::ContractAddress) -> bool;
fn get_pixels_needed(self: @TContractState) -> u32;
fn is_daily(self: @TContractState) -> bool;
fn claim_day(self: @TContractState) -> u32;
}
31 changes: 13 additions & 18 deletions onchain/src/quests/pixel_quest.cairo
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
#[starknet::interface]
trait IPixelQuest<TContractState> {
fn is_claimed(self: @TContractState, user: starknet::ContractAddress) -> bool;
fn get_pixels_needed(self: @TContractState) -> u32;
fn is_daily(self: @TContractState) -> bool;
fn claim_day(self: @TContractState) -> u32;
}

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

#[storage]
struct Storage {
Expand Down Expand Up @@ -49,26 +40,26 @@ mod PixelQuest {
#[abi(embed_v0)]
impl PixelQuestImpl of IPixelQuest<ContractState> {
fn is_claimed(self: @ContractState, user: ContractAddress) -> bool {
return self.claimed.read(user);
self.claimed.read(user)
}

fn get_pixels_needed(self: @ContractState) -> u32 {
return self.pixels_needed.read();
self.pixels_needed.read()
}

fn is_daily(self: @ContractState) -> bool {
return self.is_daily.read();
self.is_daily.read()
}

fn claim_day(self: @ContractState) -> u32 {
return self.claim_day.read();
self.claim_day.read()
}
}

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

fn is_claimable(
Expand All @@ -78,18 +69,21 @@ mod PixelQuest {
if self.claimed.read(user) {
return false;
}

if self.is_daily.read() {
// Daily Pixel Quest
let day = art_peace.get_day();
if day != self.claim_day.read() {
return false;
}
let placement_count = art_peace.get_user_pixels_placed_day(user, day);
return placement_count >= self.pixels_needed.read();

placement_count >= self.pixels_needed.read()
} else {
// Main Pixel Quest
let placement_count = art_peace.get_user_pixels_placed(user);
return placement_count >= self.pixels_needed.read();

placement_count >= self.pixels_needed.read()
}
}

Expand All @@ -105,7 +99,8 @@ mod PixelQuest {
self.claimed.write(user, true);
let reward = self.reward.read();
self.emit(QuestClaimed { user, reward, calldata });
return reward;

reward
}
}
}
13 changes: 7 additions & 6 deletions onchain/src/templates/component.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[starknet::component]
mod TemplateStoreComponent {
pub mod TemplateStoreComponent {
use art_peace::templates::interface::{ITemplateStore, TemplateMetadata};

#[storage]
Expand All @@ -13,7 +13,7 @@ mod TemplateStoreComponent {

#[event]
#[derive(Drop, starknet::Event)]
enum Event {
pub enum Event {
TemplateAdded: TemplateAdded,
TemplateCompleted: TemplateCompleted,
}
Expand All @@ -37,18 +37,19 @@ mod TemplateStoreComponent {
TContractState, +HasComponent<TContractState>
> of ITemplateStore<ComponentState<TContractState>> {
fn get_templates_count(self: @ComponentState<TContractState>) -> u32 {
return self.templates_count.read();
self.templates_count.read()
}

fn get_template(
self: @ComponentState<TContractState>, template_id: u32
) -> TemplateMetadata {
return self.templates.read(template_id);
self.templates.read(template_id)
}

fn get_template_hash(self: @ComponentState<TContractState>, template_id: u32) -> felt252 {
let metadata: TemplateMetadata = self.templates.read(template_id);
return metadata.hash;

metadata.hash
}

// TODO: Return idx of the template?
Expand All @@ -62,7 +63,7 @@ mod TemplateStoreComponent {
}

fn is_template_complete(self: @ComponentState<TContractState>, template_id: u32) -> bool {
return self.completed_templates.read(template_id);
self.completed_templates.read(template_id)
}
}
}
12 changes: 6 additions & 6 deletions onchain/src/templates/interface.cairo
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#[derive(Drop, Copy, Serde, starknet::Store)]
pub struct TemplateMetadata {
hash: felt252,
position: u128,
width: u128,
height: u128,
reward: u256,
reward_token: starknet::ContractAddress
pub hash: felt252,
pub position: u128,
pub width: u128,
pub height: u128,
pub reward: u256,
pub reward_token: starknet::ContractAddress
}

#[starknet::interface]
Expand Down
Loading

0 comments on commit 5c14814

Please sign in to comment.