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