Skip to content

Commit c46687e

Browse files
Merge branch 'base-challenge-template' into challenge-5-multisig-wallet
2 parents 0b2439f + 95c7e3a commit c46687e

1 file changed

Lines changed: 113 additions & 0 deletions

File tree

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#[starknet::interface]
2+
pub trait IYourContract<TContractState> {
3+
fn greeting(self: @TContractState) -> ByteArray;
4+
fn set_greeting(ref self: TContractState, new_greeting: ByteArray, amount_strk: Option<u256>);
5+
fn withdraw(ref self: TContractState);
6+
fn premium(self: @TContractState) -> bool;
7+
}
8+
9+
#[starknet::contract]
10+
pub mod YourContract {
11+
use openzeppelin_access::ownable::OwnableComponent;
12+
use openzeppelin_token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};
13+
use starknet::storage::{
14+
Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess,
15+
StoragePointerWriteAccess,
16+
};
17+
use starknet::{ContractAddress, get_caller_address, get_contract_address};
18+
use super::IYourContract;
19+
20+
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
21+
22+
#[abi(embed_v0)]
23+
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;
24+
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;
25+
26+
pub const FELT_STRK_CONTRACT: felt252 =
27+
0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d;
28+
29+
#[event]
30+
#[derive(Drop, starknet::Event)]
31+
enum Event {
32+
#[flat]
33+
OwnableEvent: OwnableComponent::Event,
34+
GreetingChanged: GreetingChanged,
35+
}
36+
37+
#[derive(Drop, starknet::Event)]
38+
struct GreetingChanged {
39+
#[key]
40+
greeting_setter: ContractAddress,
41+
#[key]
42+
new_greeting: ByteArray,
43+
premium: bool,
44+
value: Option<u256>,
45+
}
46+
47+
#[storage]
48+
struct Storage {
49+
greeting: ByteArray,
50+
premium: bool,
51+
total_counter: u256,
52+
user_greeting_counter: Map<ContractAddress, u256>,
53+
#[substorage(v0)]
54+
ownable: OwnableComponent::Storage,
55+
}
56+
57+
#[constructor]
58+
fn constructor(ref self: ContractState, owner: ContractAddress) {
59+
self.greeting.write("Building Unstoppable Apps!!!");
60+
self.ownable.initializer(owner);
61+
}
62+
63+
#[abi(embed_v0)]
64+
impl YourContractImpl of IYourContract<ContractState> {
65+
fn greeting(self: @ContractState) -> ByteArray {
66+
self.greeting.read()
67+
}
68+
fn set_greeting(
69+
ref self: ContractState, new_greeting: ByteArray, amount_strk: Option<u256>,
70+
) {
71+
self.greeting.write(new_greeting);
72+
self.total_counter.write(self.total_counter.read() + 1);
73+
let user_counter = self.user_greeting_counter.read(get_caller_address());
74+
self.user_greeting_counter.write(get_caller_address(), user_counter + 1);
75+
76+
match amount_strk {
77+
Option::Some(amount_strk) => {
78+
// In `Debug Contract` or UI implementation, call `approve` on STRK contract
79+
// before invoking fn set_greeting()
80+
let strk_contract_address: ContractAddress = FELT_STRK_CONTRACT
81+
.try_into()
82+
.unwrap();
83+
let strk_dispatcher = IERC20Dispatcher {
84+
contract_address: strk_contract_address,
85+
};
86+
strk_dispatcher
87+
.transfer_from(get_caller_address(), get_contract_address(), amount_strk);
88+
self.premium.write(true);
89+
},
90+
Option::None => { self.premium.write(false); },
91+
}
92+
self
93+
.emit(
94+
GreetingChanged {
95+
greeting_setter: get_caller_address(),
96+
new_greeting: self.greeting.read(),
97+
premium: true,
98+
value: amount_strk,
99+
},
100+
);
101+
}
102+
fn withdraw(ref self: ContractState) {
103+
self.ownable.assert_only_owner();
104+
let strk_contract_address = FELT_STRK_CONTRACT.try_into().unwrap();
105+
let strk_dispatcher = IERC20Dispatcher { contract_address: strk_contract_address };
106+
let balance = strk_dispatcher.balance_of(get_contract_address());
107+
strk_dispatcher.transfer(self.ownable.owner(), balance);
108+
}
109+
fn premium(self: @ContractState) -> bool {
110+
self.premium.read()
111+
}
112+
}
113+
}

0 commit comments

Comments
 (0)