-
Notifications
You must be signed in to change notification settings - Fork 3
/
AMOCoin.sol
201 lines (175 loc) · 5.59 KB
/
AMOCoin.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
pragma solidity ^0.4.18;
import 'zeppelin-solidity/contracts/token/ERC20/StandardToken.sol';
import 'zeppelin-solidity/contracts/token/ERC20/BurnableToken.sol';
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';
import 'zeppelin-solidity/contracts/math/SafeMath.sol';
contract AMOCoin is StandardToken, BurnableToken, Ownable {
using SafeMath for uint256;
string public constant symbol = "AMO";
string public constant name = "AMO Coin";
uint8 public constant decimals = 18;
uint256 public constant INITIAL_SUPPLY = 20000000000 * (10 ** uint256(decimals));
uint256 public constant TOKEN_SALE_ALLOWANCE = 10000000000 * (10 ** uint256(decimals));
uint256 public constant ADMIN_ALLOWANCE = INITIAL_SUPPLY - TOKEN_SALE_ALLOWANCE;
// Address of token administrator
address public adminAddr;
// Address of token sale contract
address public tokenSaleAddr;
// Enable transfer after token sale is completed
bool public transferEnabled = false;
// Accounts to be locked for certain period
mapping(address => uint256) private lockedAccounts;
/*
*
* Permissions when transferEnabled is false :
* ContractOwner Admin SaleContract Others
* transfer x v v x
* transferFrom x v v x
*
* Permissions when transferEnabled is true :
* ContractOwner Admin SaleContract Others
* transfer v v v v
* transferFrom v v v v
*
*/
/*
* Check if token transfer is allowed
* Permission table above is result of this modifier
*/
modifier onlyWhenTransferAllowed() {
require(transferEnabled == true
|| msg.sender == adminAddr
|| msg.sender == tokenSaleAddr);
_;
}
/*
* Check if token sale address is not set
*/
modifier onlyWhenTokenSaleAddrNotSet() {
require(tokenSaleAddr == address(0x0));
_;
}
/*
* Check if token transfer destination is valid
*/
modifier onlyValidDestination(address to) {
require(to != address(0x0)
&& to != address(this)
&& to != owner
&& to != adminAddr
&& to != tokenSaleAddr);
_;
}
modifier onlyAllowedAmount(address from, uint256 amount) {
require(balances[from].sub(amount) >= lockedAccounts[from]);
_;
}
/*
* The constructor of AMOCoin contract
*
* @param _adminAddr: Address of token administrator
*/
function AMOCoin(address _adminAddr) public {
totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = totalSupply_;
Transfer(address(0x0), msg.sender, totalSupply_);
adminAddr = _adminAddr;
approve(adminAddr, ADMIN_ALLOWANCE);
}
/*
* Set amount of token sale to approve allowance for sale contract
*
* @param _tokenSaleAddr: Address of sale contract
* @param _amountForSale: Amount of token for sale
*/
function setTokenSaleAmount(address _tokenSaleAddr, uint256 amountForSale)
external
onlyOwner
onlyWhenTokenSaleAddrNotSet
{
require(!transferEnabled);
uint256 amount = (amountForSale == 0) ? TOKEN_SALE_ALLOWANCE : amountForSale;
require(amount <= TOKEN_SALE_ALLOWANCE);
approve(_tokenSaleAddr, amount);
tokenSaleAddr = _tokenSaleAddr;
}
/*
* Set transferEnabled variable to true
*/
function enableTransfer() external onlyOwner {
transferEnabled = true;
approve(tokenSaleAddr, 0);
}
/*
* Set transferEnabled variable to false
*/
function disableTransfer() external onlyOwner {
transferEnabled = false;
}
/*
* Transfer token from message sender to another
*
* @param to: Destination address
* @param value: Amount of AMO token to transfer
*/
function transfer(address to, uint256 value)
public
onlyWhenTransferAllowed
onlyValidDestination(to)
onlyAllowedAmount(msg.sender, value)
returns (bool)
{
return super.transfer(to, value);
}
/*
* Transfer token from 'from' address to 'to' addreess
*
* @param from: Origin address
* @param to: Destination address
* @param value: Amount of AMO Coin to transfer
*/
function transferFrom(address from, address to, uint256 value)
public
onlyWhenTransferAllowed
onlyValidDestination(to)
onlyAllowedAmount(from, value)
returns (bool)
{
return super.transferFrom(from, to, value);
}
/*
* Burn token, only owner is allowed
*
* @param value: Amount of AMO Coin to burn
*/
function burn(uint256 value) public onlyOwner {
require(transferEnabled);
super.burn(value);
}
/*
* Disable transfering tokens more than allowed amount from certain account
*
* @param addr: Account to set allowed amount
* @param amount: Amount of tokens to allow
*/
function lockAccount(address addr, uint256 amount)
external
onlyOwner
onlyValidDestination(addr)
{
require(amount > 0);
lockedAccounts[addr] = amount;
}
/*
* Enable transfering tokens of locked account
*
* @param addr: Account to unlock
*/
function unlockAccount(address addr)
external
onlyOwner
onlyValidDestination(addr)
{
lockedAccounts[addr] = 0;
}
}