Skip to content

Commit 97bd7c7

Browse files
authored
Create AmisToken.sol
1 parent 55ff853 commit 97bd7c7

File tree

1 file changed

+327
-0
lines changed

1 file changed

+327
-0
lines changed

AmisToken.sol

+327
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
pragma solidity ^0.4.8;
2+
/**
3+
* https://github.com/amisolution/ERC20-AMIS/AmisToken.sol
4+
* Overflow aware uint math functions.
5+
*
6+
* Inspired by https://github.com/MakerDAO/maker-otc/blob/master/contracts/simple_market.sol
7+
*/
8+
9+
contract SafeMath {
10+
//internals
11+
12+
function safeMul(uint a, uint b) internal returns (uint) {
13+
uint c = a * b;
14+
assert(a == 0 || c / a == b);
15+
return c;
16+
}
17+
18+
function safeSub(uint a, uint b) internal returns (uint) {
19+
assert(b <= a);
20+
return a - b;
21+
}
22+
23+
function safeAdd(uint a, uint b) internal returns (uint) {
24+
uint c = a + b;
25+
assert(c>=a && c>=b);
26+
return c;
27+
}
28+
29+
function assert(bool assertion) internal {
30+
if (!assertion) throw;
31+
}
32+
}
33+
34+
/**
35+
* ERC 20 token
36+
*
37+
* https://github.com/ethereum/EIPs/issues/20
38+
*/
39+
contract Token {
40+
41+
/// @return total amount of tokens
42+
function totalSupply() constant returns (uint256 supply) {}
43+
44+
/// @param _owner The address from which the balance will be retrieved
45+
/// @return The balance
46+
function balanceOf(address _owner) constant returns (uint256 balance) {}
47+
48+
/// @notice send `_value` token to `_to` from `msg.sender`
49+
/// @param _to The address of the recipient
50+
/// @param _value The amount of token to be transferred
51+
/// @return Whether the transfer was successful or not
52+
function transfer(address _to, uint256 _value) returns (bool success) {}
53+
54+
/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
55+
/// @param _from The address of the sender
56+
/// @param _to The address of the recipient
57+
/// @param _value The amount of token to be transferred
58+
/// @return Whether the transfer was successful or not
59+
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {}
60+
61+
/// @notice `msg.sender` approves `_addr` to spend `_value` tokens
62+
/// @param _spender The address of the account able to transfer the tokens
63+
/// @param _value The amount of wei to be approved for transfer
64+
/// @return Whether the approval was successful or not
65+
function approve(address _spender, uint256 _value) returns (bool success) {}
66+
67+
/// @param _owner The address of the account owning tokens
68+
/// @param _spender The address of the account able to transfer the tokens
69+
/// @return Amount of remaining tokens allowed to spent
70+
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {}
71+
72+
event Transfer(address indexed _from, address indexed _to, uint256 _value);
73+
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
74+
75+
}
76+
77+
/**
78+
* ERC 20 token
79+
*
80+
* https://github.com/ethereum/EIPs/issues/20
81+
*/
82+
contract StandardToken is Token {
83+
84+
/**
85+
* Reviewed:
86+
* - Interger overflow = OK, checked
87+
*/
88+
function transfer(address _to, uint256 _value) returns (bool success) {
89+
//Default assumes totalSupply can't be over max (2^256 - 1).
90+
//If your token leaves out totalSupply and can issue more tokens as time goes on, you need to check if it doesn't wrap.
91+
//Replace the if with this one instead.
92+
if (balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
93+
//if (balances[msg.sender] >= _value && _value > 0) {
94+
balances[msg.sender] -= _value;
95+
balances[_to] += _value;
96+
Transfer(msg.sender, _to, _value);
97+
return true;
98+
} else { return false; }
99+
}
100+
101+
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
102+
//same as above. Replace this line with the following if you want to protect against wrapping uints.
103+
if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
104+
//if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
105+
balances[_to] += _value;
106+
balances[_from] -= _value;
107+
allowed[_from][msg.sender] -= _value;
108+
Transfer(_from, _to, _value);
109+
return true;
110+
} else { return false; }
111+
}
112+
113+
function balanceOf(address _owner) constant returns (uint256 balance) {
114+
return balances[_owner];
115+
}
116+
117+
function approve(address _spender, uint256 _value) returns (bool success) {
118+
allowed[msg.sender][_spender] = _value;
119+
Approval(msg.sender, _spender, _value);
120+
return true;
121+
}
122+
123+
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
124+
return allowed[_owner][_spender];
125+
}
126+
127+
mapping(address => uint256) balances;
128+
129+
mapping (address => mapping (address => uint256)) allowed;
130+
131+
uint256 public totalSupply = 20000000000000000;
132+
133+
}
134+
135+
136+
/**
137+
* Amis crowdsale crowdsale contract.
138+
*
139+
* Security criteria evaluated against http://ethereum.stackexchange.com/questions/8551/methodological-security-review-of-a-smart-contract
140+
*
141+
*
142+
*/
143+
contract AmisToken is StandardToken, SafeMath {
144+
145+
string public name = "AMIS";
146+
string public symbol = "AMIS";
147+
uint public decimals = 3;
148+
uint public startBlock = 3182017; // crowdsale start block (set in constructor)
149+
uint public endBlock = 3661966; //crowdsale end block (set in constructor)
150+
151+
// Initial multisig address (set in constructor)
152+
// All deposited ETH will be instantly forwarded to this address.
153+
// Address is a multisig wallet.
154+
address public multisig = 0xB585FC61C9590EE27Eb1d955ac3AdDC5d2a14B3a;
155+
156+
address public founder = 0xaefcD0F8a1cbD231CecAA9bfd9Ffb82a6eaaa462;
157+
address public developer = 0x3D48587aA16D91a2e37198B5B428674bDADdf038;
158+
address public rewards = 0x0;
159+
bool public rewardAddressesSet = false;
160+
161+
address public owner = 0xaefcD0F8a1cbD231CecAA9bfd9Ffb82a6eaaa462;
162+
bool public marketactive = false;
163+
164+
uint public etherCap = 6720 * 10**3; //max amount raised during crowdsale (6720ETH worth of ether will be measured with a moving average market price at beginning of the crowdsale)
165+
uint public rewardsAllocation = 2; //2% tokens allocated post-crowdsale for swarm rewards
166+
uint public developerAllocation = 6 ; //6% of token supply allocated post-crowdsale for the developer fund
167+
uint public founderAllocation = 8; //8% of token supply allocated post-crowdsale for the founder allocation
168+
bool public allocated = false; //this will change to true when the rewards are allocated
169+
uint public presaleTokenSupply = 0; //this will keep track of the token supply created during the crowdsale
170+
uint public presaleEtherRaised = 0; //this will keep track of the Ether raised during the crowdsale
171+
bool public halted = false; //the founder address can set this to true to halt the crowdsale due to emergency
172+
event Buy(address indexed sender, uint eth, uint fbt);
173+
174+
function AmisToken(address multisigInput, uint startBlockInput, uint endBlockInput) {
175+
owner = msg.sender;
176+
multisig = multisigInput;
177+
178+
startBlock = startBlockInput;
179+
endBlock = endBlockInput;
180+
181+
// added for testing the AMIS->SIM conversion
182+
balances[msg.sender] = 1000 * 1 ether;
183+
}
184+
185+
function setRewardAddresses(address founderInput, address developerInput, address rewardsInput){
186+
if (msg.sender != owner) throw;
187+
if (rewardAddressesSet) throw;
188+
founder = founderInput;
189+
developer = developerInput;
190+
rewards = rewardsInput;
191+
rewardAddressesSet = true;
192+
}
193+
194+
function price() constant returns(uint) {
195+
return testPrice(block.number);
196+
}
197+
198+
// price() exposed for unit tests
199+
function testPrice(uint blockNumber) constant returns(uint) {
200+
if (blockNumber>=startBlock && blockNumber<startBlock+250) return 125; //power hour
201+
if (blockNumber<startBlock || blockNumber>endBlock) return 75; //default price
202+
return 75 + 4*(endBlock - blockNumber)/(endBlock - startBlock + 1)*34/4; //crowdsale price
203+
}
204+
205+
/**
206+
* Main token buy function.
207+
*
208+
* Security review
209+
*
210+
* - Integer math: ok - using SafeMath
211+
*
212+
* - halt flag added - ok
213+
*
214+
* Applicable tests:
215+
*
216+
* - Test halting, buying, and failing
217+
* - Test buying on behalf of a recipient
218+
* - Test buy
219+
* - Test unhalting, buying, and succeeding
220+
* - Test buying after the sale ends
221+
*
222+
*/
223+
function buyRecipient(address recipient) payable{
224+
if (block.number<startBlock || block.number>endBlock || safeAdd(presaleEtherRaised,msg.value)>etherCap || halted) throw;
225+
uint tokens = safeMul(msg.value, price());
226+
balances[recipient] = safeAdd(balances[recipient], tokens);
227+
totalSupply = safeAdd(totalSupply, tokens);
228+
presaleEtherRaised = safeAdd(presaleEtherRaised, msg.value);
229+
230+
if (!multisig.send(msg.value)) throw; //immediately send Ether to multisig address
231+
232+
// if etherCap is reached - activate the market
233+
if (presaleEtherRaised == etherCap && !marketactive){
234+
marketactive = true;
235+
}
236+
237+
Buy(recipient, msg.value, tokens);
238+
239+
}
240+
241+
/**
242+
* Set up founder address token balance.
243+
*
244+
* allocateBountyAndEcosystemTokens() must be calld first.
245+
*
246+
* Security review
247+
*
248+
* - Integer math: ok - only called once with fixed parameters
249+
*
250+
* Applicable tests:
251+
*
252+
* - Test bounty and ecosystem allocation
253+
* - Test bounty and ecosystem allocation twice
254+
*
255+
*/
256+
function allocateTokens() {
257+
// make sure founder/developer/rewards addresses are configured
258+
if(founder == 0x0 || developer == 0x0 || rewards == 0x0) throw;
259+
// owner/founder/developer/rewards addresses can call this function
260+
if (msg.sender != owner && msg.sender != founder && msg.sender != developer && msg.sender != rewards ) throw;
261+
// it should only continue if endBlock has passed OR presaleEtherRaised has reached the cap
262+
if (block.number <= endBlock && presaleEtherRaised < etherCap) throw;
263+
if (allocated) throw;
264+
presaleTokenSupply = totalSupply;
265+
// total token allocations add up to 16% of total coins, so formula is reward=allocation_in_percent/84 .
266+
balances[founder] = safeAdd(balances[founder], presaleTokenSupply * founderAllocation / 84 );
267+
totalSupply = safeAdd(totalSupply, presaleTokenSupply * founderAllocation / 84);
268+
269+
balances[developer] = safeAdd(balances[developer], presaleTokenSupply * developerAllocation / 84);
270+
totalSupply = safeAdd(totalSupply, presaleTokenSupply * developerAllocation / 84);
271+
272+
balances[rewards] = safeAdd(balances[rewards], presaleTokenSupply * rewardsAllocation / 84);
273+
totalSupply = safeAdd(totalSupply, presaleTokenSupply * rewardsAllocation / 84);
274+
275+
allocated = true;
276+
277+
}
278+
279+
/**
280+
* Emergency Stop crowdsale.
281+
*
282+
* Applicable tests:
283+
*
284+
* - Test unhalting, buying, and succeeding
285+
*/
286+
function halt() {
287+
if (msg.sender!=founder && msg.sender != developer) throw;
288+
halted = true;
289+
}
290+
291+
function unhalt() {
292+
if (msg.sender!=founder && msg.sender != developer) throw;
293+
halted = false;
294+
}
295+
296+
/**
297+
* ERC 20 Standard Token interface transfer function
298+
*
299+
* Prevent transfers until token sale is over.
300+
*
301+
* Applicable tests:
302+
*
303+
* - Test transfer after restricted period
304+
* - Test transfer after market activated
305+
*/
306+
function transfer(address _to, uint256 _value) returns (bool success) {
307+
if (block.number <= endBlock && marketactive == false) throw;
308+
return super.transfer(_to, _value);
309+
}
310+
/**
311+
* ERC 20 Standard Token interface transfer function
312+
*
313+
* Prevent transfers until token sale is over.
314+
*/
315+
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
316+
if (block.number <= endBlock && marketactive == false) throw;
317+
return super.transferFrom(_from, _to, _value);
318+
}
319+
320+
/**
321+
* Direct deposits buys tokens
322+
*/
323+
function() payable {
324+
buyRecipient(msg.sender);
325+
}
326+
327+
}

0 commit comments

Comments
 (0)