-
Notifications
You must be signed in to change notification settings - Fork 0
/
MyTokenAdvanced.sol
224 lines (175 loc) · 8.38 KB
/
MyTokenAdvanced.sol
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
pragma solidity ^0.5.16;
contract Administrable {
address private _admin;
event AdminshipTransferred(address indexed currentAdmin, address indexed newAdmin);
constructor() internal {
_admin = msg.sender;
emit AdminshipTransferred(address(0), _admin);
}
function admin() public view returns (address) {
return _admin;
}
modifier onlyAdmin() {
require(msg.sender == _admin, "Only Admin can perform this action.");
_;
}
function transferAdminship(address newAdmin) public onlyAdmin {
emit AdminshipTransferred(_admin, newAdmin);
_admin = newAdmin;
}
}
contract MyToken {
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
string private _name;
string private _symbol;
uint8 private _decimals;
uint256 private _totalSupply;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
constructor(uint256 initialSupply, string memory tokenName, string memory tokenSymbol, uint8 decimalUnits) public {
_balances[msg.sender] = initialSupply;
_totalSupply = initialSupply;
_decimals = decimalUnits;
_symbol = tokenSymbol;
_name = tokenName;
}
function name() public view returns (string memory) {
return _name;
}
function symbol() public view returns (string memory) {
return _symbol;
}
function decimals() public view returns (uint8) {
return _decimals;
}
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
function setTotalSupply(uint256 totalAmount) internal {
_totalSupply = totalAmount;
}
function balanceOf(address account) public view returns (uint256) {
return _balances[account];
}
function setBalance(address account, uint256 balance) internal {
_balances[account] = balance;
}
function allowance(address owner, address spender) public view returns (uint256) {
return _allowances[owner][spender];
}
function setAllowance(address owner, address spender, uint256 amount) internal {
_allowances[owner][spender] = amount;
}
function transfer(address beneficiary, uint256 amount) public returns (bool) {
require(beneficiary != address(0), "Beneficiary address cannot be zero.");
require(_balances[msg.sender] >= amount, "Sender does not have enough balance.");
require(_balances[beneficiary] + amount > _balances[beneficiary], "Addition overflow");
_balances[msg.sender] -= amount;
_balances[beneficiary] += amount;
emit Transfer(msg.sender, beneficiary, amount);
return true;
}
function approve(address spender, uint256 amount) public returns (bool success) {
require(spender != address(0), "Spender address cannot be zero.");
_allowances[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(address sender, address beneficiary, uint256 amount) public returns (bool) {
require(sender != address(0), "Sender address cannot be zero.");
require(beneficiary != address(0), "Beneficiary address cannot be zero.");
require(amount <= _allowances[sender][msg.sender], "Allowance is not enough");
require(_balances[sender] >= amount, "Sender does not have enough balance.");
require(_balances[beneficiary] + amount > _balances[beneficiary], "Addition overflow");
_balances[sender] -= amount;
_allowances[sender][msg.sender] -= amount;
_balances[beneficiary] += amount;
emit Transfer(sender, beneficiary, amount);
return true;
}
}
contract MyTokenAdvanced is MyToken, Administrable {
mapping (address => bool) private _frozenAccounts;
mapping (address => uint) private _pendingWithdrawals;
uint256 private _sellPrice = 1; // ether per token
uint256 private _buyPrice = 1; // ether per token
event FrozenFund(address indexed target, bool frozen);
constructor(uint256 initialSupply, string memory tokenName, string memory tokenSymbol, uint8 decimalUnits, address newAdmin) public
MyToken(0, tokenName, tokenSymbol, decimalUnits) {
if(newAdmin != address(0) && newAdmin != msg.sender)
transferAdminship(newAdmin);
setBalance(admin(), initialSupply);
setTotalSupply(initialSupply);
}
function sellPrice() public view returns (uint256) {
return _sellPrice;
}
function buyPrice() public view returns (uint256) {
return _buyPrice;
}
function setPrices(uint256 newSellPrice, uint256 newBuyPrice) public onlyAdmin {
require(newSellPrice > 0, "Sell price cannot be zero.");
require(newBuyPrice > 0, "Buy price cannot be zero.");
_sellPrice = newSellPrice;
_buyPrice = newBuyPrice;
}
function mintToken(address target, uint256 mintedAmount) public onlyAdmin {
require(balanceOf(target) + mintedAmount > balanceOf(target), "Addition overflow");
require(totalSupply() + mintedAmount > totalSupply(), "Addition overflow");
setBalance(target, balanceOf(target) + mintedAmount);
setTotalSupply(totalSupply() + mintedAmount);
emit Transfer(address(0), target, mintedAmount);
}
function freezeAccount(address target, bool freeze) public onlyAdmin {
_frozenAccounts[target] = freeze;
emit FrozenFund(target, freeze);
}
function transfer(address beneficiary, uint256 amount) public returns (bool) {
require(beneficiary != address(0), "Beneficiary address cannot be zero.");
require(balanceOf(msg.sender) >= amount, "Sender does not have enough balance.");
require(balanceOf(beneficiary) + amount > balanceOf(beneficiary), "Addition overflow");
require(!_frozenAccounts[msg.sender], "Sender's account is frozen.");
setBalance(msg.sender, balanceOf(msg.sender) - amount);
setBalance(beneficiary, balanceOf(beneficiary) + amount);
emit Transfer(msg.sender, beneficiary, amount);
return true;
}
function transferFrom(address sender, address beneficiary, uint256 amount) public returns (bool) {
require(sender != address(0), "Sender address cannot be zero.");
require(beneficiary != address(0), "Beneficiary address cannot be zero.");
require(amount <= allowance(sender, msg.sender), "Allowance is not enough");
require(balanceOf(sender) >= amount, "Sender does not have enough balance.");
require(balanceOf(beneficiary) + amount > balanceOf(beneficiary), "Addition overflow");
require(!_frozenAccounts[sender], "Sender's account is frozen.");
setBalance(sender, balanceOf(sender) - amount);
setAllowance(sender, msg.sender, allowance(sender, msg.sender) - amount);
setBalance(beneficiary, balanceOf(beneficiary) + amount);
emit Transfer(sender, beneficiary, amount);
return true;
}
function buy() public payable {
uint256 amount = (msg.value/(1 ether)) / _buyPrice;
address thisContractAddress = address(this);
require(balanceOf(thisContractAddress) >= amount, "Contract does not have enough tokens.");
require(balanceOf(msg.sender) + amount > balanceOf(msg.sender), "Addition overflow");
setBalance(thisContractAddress, balanceOf(thisContractAddress) - amount);
setBalance(msg.sender, balanceOf(msg.sender) + amount);
emit Transfer(thisContractAddress, msg.sender, amount);
}
function sell(uint256 amount) public {
address thisContractAddress = address(this);
require(balanceOf(msg.sender) >= amount, "Seller does not have enough tokens.");
require(balanceOf(thisContractAddress) + amount > balanceOf(thisContractAddress), "Addition overflow");
setBalance(msg.sender, balanceOf(msg.sender) - amount);
setBalance(thisContractAddress, balanceOf(thisContractAddress) + amount);
uint256 saleProceed = amount * _sellPrice * (1 ether);
_pendingWithdrawals[msg.sender] += saleProceed;
emit Transfer(msg.sender, thisContractAddress, amount);
}
function withdraw() public {
uint amount = _pendingWithdrawals[msg.sender];
_pendingWithdrawals[msg.sender] = 0;
msg.sender.transfer(amount);
}
}