Skip to content

Commit ec7b01f

Browse files
authored
Merge pull request #1 from aji70/main
feat: added the pause, unpause and whitelist functionality
2 parents d4e3116 + 159c8b9 commit ec7b01f

4 files changed

Lines changed: 403 additions & 123 deletions

File tree

.github/workflows/test.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Build and Test
2+
3+
on: [push, pull_request]
4+
permissions: read-all
5+
6+
jobs:
7+
build:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v3
11+
- uses: software-mansion/setup-scarb@v1
12+
with:
13+
scarb-version: 2.8.4
14+
- name: Check cairo format
15+
run: scarb fmt --check
16+
- name: Build cairo programs
17+
run: scarb build
18+
19+
test:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v3
23+
- uses: software-mansion/setup-scarb@v1
24+
with:
25+
scarb-version: 2.8.4
26+
- uses: foundry-rs/setup-snfoundry@v3
27+
with:
28+
starknet-foundry-version: 0.37.0
29+
- name: Run cairo tests
30+
run: snforge test

src/interfaces.cairo

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ use loop_starknet::factory::TribesNftFactory::Collection;
77
#[starknet::interface]
88
pub trait IERC721<TContractState> {
99
fn mint_ticket_nft(ref self: TContractState, recipient: ContractAddress, token_id: u256);
10-
fn burn_nft(ref self: TContractState, token_id: u256);
10+
fn burn_nft(ref self: TContractState, token_id: u256);
11+
fn pause(ref self: TContractState);
12+
fn unpause(ref self: TContractState);
13+
fn whitelist_address(ref self: TContractState, address: ContractAddress);
14+
fn is_whitelisted(ref self: TContractState, address: ContractAddress) -> bool;
1115
}
1216

1317

@@ -46,7 +50,7 @@ pub trait IVault<TContractState> {
4650
);
4751
fn burn_expired_pass(ref self: TContractState, token_id: u32, user: ContractAddress);
4852

49-
fn check_pass_status(self: @TContractState,user: ContractAddress, token_id: u32) -> bool;
53+
fn check_pass_status(self: @TContractState, user: ContractAddress, token_id: u32) -> bool;
5054
fn get_validity(self: @TContractState, token_id: u32) -> TribePassValidity;
5155
fn get_artist_info(self: @TContractState, artist_address: ContractAddress) -> ArtistDetails;
5256
fn get_user_pass(self: @TContractState, user: ContractAddress) -> PassDetails;

src/nfts/tribes_nft.cairo

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
21
const PAUSER_ROLE: felt252 = selector!("PAUSER_ROLE");
32
const MINTER_ROLE: felt252 = selector!("MINTER_ROLE");
43

54
#[starknet::contract]
65
pub mod TribesNFT {
76
use starknet::{ContractAddress, get_caller_address};
8-
use starknet::storage::{StoragePointerWriteAccess, StoragePointerReadAccess};
7+
use starknet::storage::{Map, StorageMapReadAccess, StorageMapWriteAccess,};
98
use core::num::traits::Zero;
109
use openzeppelin::access::accesscontrol::AccessControlComponent;
1110
use openzeppelin::introspection::src5::SRC5Component;
@@ -44,7 +43,8 @@ pub mod TribesNFT {
4443
pausable: PausableComponent::Storage,
4544
#[substorage(v0)]
4645
accesscontrol: AccessControlComponent::Storage,
47-
next_token_id: u256
46+
next_token_id: u256,
47+
whitelist: Map<ContractAddress, bool>,
4848
}
4949

5050
#[event]
@@ -93,33 +93,60 @@ pub mod TribesNFT {
9393
#[abi(embed_v0)]
9494
impl IERC721Impl of IERC721<ContractState> {
9595
fn burn_nft(ref self: ContractState, token_id: u256) {
96+
let owner = self.erc721.ownerOf(token_id);
97+
self.whitelist.write(owner, false);
9698
self.erc721.update(Zero::zero(), token_id, get_caller_address());
9799
}
98100

99101
fn mint_ticket_nft(ref self: ContractState, recipient: ContractAddress, token_id: u256) {
102+
let is_whitelisted = self.whitelist.read(recipient);
103+
assert(is_whitelisted, 'Not Whitelisted');
100104
let balance = self.erc721.balance_of(recipient);
101105
assert(balance.is_zero(), 'ALREADY_MINTED');
102106

103107
self._mint(recipient, token_id);
104108
}
105-
}
106109

107-
// Additional functions not part of the IERC721 interface
108-
#[generate_trait]
109-
#[abi(per_item)]
110-
impl ExternalImpl of ExternalTrait {
111-
#[external(v0)]
112110
fn pause(ref self: ContractState) {
113111
self.accesscontrol.assert_only_role(PAUSER_ROLE);
114112
self.pausable.pause();
115113
}
116114

117-
#[external(v0)]
115+
118116
fn unpause(ref self: ContractState) {
119117
self.accesscontrol.assert_only_role(PAUSER_ROLE);
120118
self.pausable.unpause();
121119
}
122120

121+
fn whitelist_address(ref self: ContractState, address: ContractAddress) {
122+
self.accesscontrol.assert_only_role(PAUSER_ROLE);
123+
let is_whitelisted = self.whitelist.read(address);
124+
assert(!is_whitelisted, 'Already Whitelisted');
125+
self.whitelist.write(address, true);
126+
}
127+
128+
fn is_whitelisted(ref self: ContractState, address: ContractAddress) -> bool {
129+
let is_whitelisted = self.whitelist.read(address);
130+
is_whitelisted
131+
}
132+
}
133+
134+
// Additional functions not part of the IERC721 interface
135+
#[generate_trait]
136+
#[abi(per_item)]
137+
impl ExternalImpl of ExternalTrait {
138+
// #[external(v0)]
139+
// fn pause(ref self: ContractState) {
140+
// self.accesscontrol.assert_only_role(PAUSER_ROLE);
141+
// self.pausable.pause();
142+
// }
143+
144+
// #[external(v0)]
145+
// fn unpause(ref self: ContractState) {
146+
// self.accesscontrol.assert_only_role(PAUSER_ROLE);
147+
// self.pausable.unpause();
148+
// }
149+
123150
#[external(v0)]
124151
fn _mint(ref self: ContractState, recipient: ContractAddress, token_id: u256,) {
125152
// self.accesscontrol.assert_only_role(MINTER_ROLE);
@@ -137,4 +164,4 @@ pub mod TribesNFT {
137164
self.erc721.safe_mint(recipient, token_id, data);
138165
}
139166
}
140-
}
167+
}

0 commit comments

Comments
 (0)