forked from pumpbtc/pumpBTC-cairo
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlib.cairo
More file actions
110 lines (94 loc) · 3.46 KB
/
lib.cairo
File metadata and controls
110 lines (94 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts for Cairo ^0.19.0
#[starknet::contract]
mod PumpBTC {
use core::num::traits::Zero;
use openzeppelin::access::ownable::OwnableComponent;
use openzeppelin::token::erc20::ERC20Component;
use openzeppelin::token::erc20::ERC20HooksEmptyImpl;
use starknet::{ContractAddress, get_caller_address};
use starknet::storage::{Map, StorageMapReadAccess, StorageMapWriteAccess};
component!(path: ERC20Component, storage: erc20, event: ERC20Event);
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
#[abi(embed_v0)]
impl ERC20MixinImpl = ERC20Component::ERC20MixinImpl<ContractState>;
#[abi(embed_v0)]
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;
#[storage]
struct Storage {
#[substorage(v0)]
erc20: ERC20Component::Storage,
#[substorage(v0)]
ownable: OwnableComponent::Storage,
is_minter: Map<ContractAddress, bool>,
}
#[derive(Drop, Debug, PartialEq, starknet::Event)]
pub struct MinterSet {
pub minter: ContractAddress,
pub status: bool,
}
#[derive(Drop, Debug, PartialEq, starknet::Event)]
pub struct Mint {
pub to: ContractAddress,
pub amount: u256,
}
#[derive(Drop, Debug, PartialEq, starknet::Event)]
pub struct Burn {
pub from: ContractAddress,
pub amount: u256,
}
#[event]
#[derive(Drop, starknet::Event)]
enum Event {
#[flat]
ERC20Event: ERC20Component::Event,
#[flat]
OwnableEvent: OwnableComponent::Event,
MinterSet: MinterSet,
Mint: Mint,
Burn: Burn,
}
#[constructor]
fn constructor(ref self: ContractState, owner: ContractAddress) {
self.erc20.initializer("pumpBTC", "pumpBTC");
self.ownable.initializer(owner);
}
#[generate_trait]
#[abi(per_item)]
impl ExternalImpl of ExternalTrait {
#[external(v0)]
fn is_minter(self: @ContractState, minter: ContractAddress) -> bool {
self.is_minter.read(minter)
}
fn assert_only_minter(self: @ContractState) {
let caller = get_caller_address();
assert(!caller.is_zero(), 'Zero Caller');
assert(self.is_minter.read(caller), 'Not Minter');
}
fn assert_not_zero_amount(self: @ContractState, amount: u256) {
assert(amount > 0, 'Zero Amount');
}
#[external(v0)]
fn set_minter(ref self: ContractState, minter: ContractAddress, status: bool) {
self.ownable.assert_only_owner();
self.is_minter.write(minter, status);
self.emit(MinterSet { minter, status });
}
#[external(v0)]
fn mint(ref self: ContractState, to: ContractAddress, amount: u256) {
self.assert_not_zero_amount(amount);
self.assert_only_minter();
self.erc20.mint(to, amount);
self.emit(Mint { to, amount });
}
#[external(v0)]
fn burn(ref self: ContractState, from: ContractAddress, amount: u256) {
self.assert_not_zero_amount(amount);
self.assert_only_minter();
self.erc20.burn(from, amount);
self.emit(Burn { from, amount });
}
}
}