erc20_secure/
erc20.rs

1use std::collections::BTreeMap;
2
3use crate::data;
4use crate::event::*;
5use alloc::string::String;
6use casper_erc20_crate::{Address, Error, ERC20 as CasperErc20};
7use casper_types::ContractHash;
8use casper_types::Key;
9use casper_types::{ContractPackageHash, U256};
10use casperlabs_contract_utils::{ContractContext, ContractStorage};
11use casperlabs_ownable::OWNABLE;
12use casper_contract::contract_api::storage;
13use casper_contract::contract_api::runtime;
14
15pub trait ERC20<Storage: ContractStorage>: 
16    ContractContext<Storage> + OWNABLE<Storage> {
17    fn init(&mut self, contract_hash: ContractHash, package_hash: ContractPackageHash) {
18        OWNABLE::init(self, contract_hash, package_hash);
19        data::set_contract_hash(contract_hash);
20        data::set_package_hash(package_hash);
21    }
22
23    fn name(&self) -> String {
24        CasperErc20::default().name()
25    }
26
27    fn symbol(&self) -> String {
28        CasperErc20::default().symbol()
29    }
30
31    fn decimals(&self) -> u8 {
32        CasperErc20::default().decimals()
33    }
34
35    fn total_supply(&self) -> U256 {
36        CasperErc20::default().total_supply()
37    }
38
39    fn balance_of(&self, owner: Address) -> U256 {
40        CasperErc20::default().balance_of(owner)
41    }
42
43    fn allowance(&self, owner: Address, spender: Address) -> U256 {
44        CasperErc20::default().allowance(owner, spender)
45    }
46
47    fn increase_allowance(&self, spender: Address, amount: U256) -> Result<(), Error> {
48        CasperErc20::default().increase_allowance(spender, amount)
49    }
50
51    fn decrease_allowance(&self, spender: Address, amount: U256) -> Result<(), Error> {
52        CasperErc20::default().decrease_allowance(spender, amount)
53    }
54
55    fn transfer(&self, recipient: Address, amount: U256) -> Result<(), Error> {
56        let ret = CasperErc20::default().transfer(recipient, amount);
57        if ret.is_ok() {
58            emit(&ERC20Event::Transfer {
59                from: self.get_caller(),
60                to: Key::from(recipient),
61                value: amount,
62            });
63        }
64        ret
65    }
66
67    fn _approve(&self, owner: Address, spender: Address, value: U256) -> Result<(), Error> {
68        let ret = CasperErc20::default()._approve(owner, spender, value);
69        if ret.is_ok() {
70            emit(&ERC20Event::Approval {
71                owner: Key::from(owner),
72                spender: Key::from(spender),
73                value,
74            });
75        }
76        ret
77    }
78
79    fn approve(&self, spender: Address, value: U256) -> Result<(), Error> {
80        self._approve(Address::from(self.get_caller()), spender, value)
81    }
82
83    fn transfer_from(&self, from: Address, to: Address, value: U256) -> Result<(), Error> {
84        let ret = CasperErc20::default().transfer_from(from, to, value);
85        if ret.is_ok() {
86            emit(&ERC20Event::Transfer {
87                from: Key::from(from),
88                to: Key::from(to),
89                value,
90            });
91        }
92        ret
93    }
94
95    fn mint(&self, to: Address, value: U256) -> Result<(), Error> {
96        OWNABLE::only_owner(self);
97        let ret = CasperErc20::default().mint(to, value);
98        if ret.is_ok() {
99            emit(&ERC20Event::Transfer {
100                from: Key::from_formatted_str(
101                    "hash-0000000000000000000000000000000000000000000000000000000000000000",
102                )
103                .unwrap(),
104                to: Key::from(to),
105                value,
106            });
107        }
108        ret
109    }
110
111    fn burn(&self, from: Address, value: U256) -> Result<(), Error> {
112        OWNABLE::only_owner(self);
113        let ret = CasperErc20::default().burn(from, value);
114        if ret.is_ok() {
115            emit(&ERC20Event::Transfer {
116                from: Key::from(from),
117                to: Key::from_formatted_str(
118                    "hash-0000000000000000000000000000000000000000000000000000000000000000",
119                )
120                .unwrap(),
121                value,
122            });
123        }
124        ret
125    }
126
127    fn named_keys(
128        &self,
129        name: String,
130        symbol: String,
131        decimals: u8,
132        initial_supply: U256,
133        package_hash: ContractPackageHash,
134    ) -> Result<BTreeMap<String, Key>, Error> {
135        let ret = CasperErc20::default().named_keys(name, symbol, decimals, initial_supply);
136        if ret.is_ok() {
137            let mut event = BTreeMap::new();
138            event.insert("contract_package_hash", package_hash.to_string());
139            event.insert("event_type", "transfer".to_string());
140            event.insert("from", data::zero_address().to_string());
141            event.insert("to", Key::from(runtime::get_caller()).to_string());
142            event.insert("value", initial_supply.to_string());
143            storage::new_uref(event);
144        }
145        ret
146    }
147}