Guest User

Untitled

a guest
Nov 24th, 2017
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.67 KB | None | 0 0
  1. pragma solidity 0.4.15;
  2. import './Owned.sol';
  3. import './CrowdsaleParameters.sol';
  4. import './TokenRecipient.sol';
  5. import './ShortAddressAtackFix.sol';
  6.  
  7. contract SeedToken is Owned, CrowdsaleParameters, ShortAddressAtackFix {
  8.  
  9. /* Public variables of the token */
  10. string public standard = "Token 0.1";
  11.  
  12. string public name = "Seed";
  13.  
  14. string public symbol = "SED";
  15.  
  16. uint8 public decimals = 18;
  17.  
  18. /* This creates an array with all balances */
  19. mapping (address => uint256) private balances;
  20.  
  21. mapping (address => mapping (uint256 => uint256)) public vestingBalanceOf;
  22.  
  23. uint[] private vestingTimes;
  24.  
  25. mapping (address => mapping (address => uint256)) private allowed;
  26. mapping (address => mapping (address => bool)) private allowanceUsed;
  27.  
  28. uint256 private _totalSupply = 0;
  29.  
  30. /* This generates a public event on the blockchain that will notify clients */
  31. event Transfer(address indexed from, address indexed to, uint256 value);
  32.  
  33. event Transfer(address indexed spender, address indexed from, address indexed to, uint256 value);
  34.  
  35. event VestingTransfer(address indexed from, address indexed to, uint256 value, uint256 vestingTime);
  36.  
  37. event Approval(address indexed _owner, address indexed _spender, uint256 _value);
  38.  
  39. // triggered when the total supply is increased
  40. event Issuance(uint256 _amount);
  41.  
  42. // triggered when the total supply is decreased
  43. event Destruction(uint256 _amount);
  44.  
  45. address[] public addressByIndex;
  46.  
  47. mapping (address => bool) private addressAddedToIndex;
  48.  
  49. mapping (address => uint) private vestingTimesForPools;
  50.  
  51. bool public transfersEnabled = true;
  52.  
  53. event NewSeedToken(address _token);
  54.  
  55. /**
  56. * Constructor
  57. *
  58. * Initializes contract with initial supply tokens to the creator of the contract
  59. *
  60. * Fail to create contract if decimals is greater than 18. This allows to
  61. * avoid using SafeMath for internal methods for token operations because
  62. * there will be no overflow:
  63. *
  64. * uint256 provides roughly 10^77 range. The nubmer to express the greatest
  65. * amount of tokens possible (if decimals == 18) is approx.
  66. * 10^18 * 10^9 = 10^27 => no overflow possible.
  67. */
  68. function SeedToken() public {
  69. require(decimals <= 18);
  70. owner = msg.sender;
  71.  
  72. addVestingTimesForPool(CrowdsaleParameters.presalePoolAddress, CrowdsaleParameters.presalePoolVestingTime);
  73. addVestingTimesForPool(CrowdsaleParameters.foundersAddress, CrowdsaleParameters.foundersVestingTime);
  74. addVestingTimesForPool(CrowdsaleParameters.incentiveReserveAddress, CrowdsaleParameters.incentiveReserveVestingTime);
  75. addVestingTimesForPool(CrowdsaleParameters.generalSaleAddress, CrowdsaleParameters.generalSaleVestingTime);
  76. addVestingTimesForPool(CrowdsaleParameters.lotteryAddress, CrowdsaleParameters.lotteryVestingTime);
  77. addVestingTimesForPool(CrowdsaleParameters.marketingAddress, CrowdsaleParameters.marketingVestingTime);
  78.  
  79. addVestingTime(CrowdsaleParameters.presalePoolVestingTime);
  80. addVestingTime(CrowdsaleParameters.foundersVestingTime);
  81. addVestingTime(CrowdsaleParameters.incentiveReserveVestingTime);
  82. addVestingTime(CrowdsaleParameters.generalSaleVestingTime);
  83. addVestingTime(CrowdsaleParameters.lotteryVestingTime);
  84. addVestingTime(CrowdsaleParameters.marketingVestingTime);
  85.  
  86. uint uintDecimals = decimals;
  87. uint exponent = 10**uintDecimals;
  88. mintToken(CrowdsaleParameters.generalSaleAddress, 170000000 * exponent, 0);
  89. mintToken(CrowdsaleParameters.foundersAddress, 26000000 * exponent, 0);
  90. mintToken(CrowdsaleParameters.presalePoolAddress, 35000000 * exponent, 0);
  91. mintToken(CrowdsaleParameters.incentiveReserveAddress, 17362500 * exponent, 0);
  92. mintToken(CrowdsaleParameters.lotteryAddress, 200000 * exponent, 0);
  93. mintToken(CrowdsaleParameters.marketingAddress, 7687500 * exponent, 0);
  94.  
  95. NewSeedToken(address(this));
  96. }
  97.  
  98. /**
  99. * verifies that transfers are enabled
  100. */
  101. modifier transfersAllowed {
  102. require(transfersEnabled);
  103. _;
  104. }
  105.  
  106. /**
  107. * 1. Associate crowdsale contract address with this Token
  108. * 2. Allocate presale and general sale amounts
  109. * 3. Allocate all other amounts (such as Founder's pool, incentive,
  110. * lottery and marketing)
  111. *
  112. * @param _crowdsaleAddress - crowdsale contract address
  113. */
  114. function approveForCrowdsale(address _crowdsaleAddress) public onlyOwner {
  115. uint uintDecimals = decimals;
  116. uint exponent = 10**uintDecimals;
  117.  
  118. allowed[CrowdsaleParameters.generalSaleAddress][_crowdsaleAddress] = 170000000 * exponent;
  119. allowed[CrowdsaleParameters.presalePoolAddress][_crowdsaleAddress] = 35000000 * exponent;
  120. Approval(CrowdsaleParameters.generalSaleAddress, _crowdsaleAddress, 170000000 * exponent);
  121. Approval(CrowdsaleParameters.presalePoolAddress, _crowdsaleAddress, 35000000 * exponent);
  122.  
  123. allowed[CrowdsaleParameters.foundersAddress][_crowdsaleAddress] = 26000000 * exponent;
  124. Approval(CrowdsaleParameters.foundersAddress, _crowdsaleAddress, 26000000 * exponent);
  125.  
  126. allowed[CrowdsaleParameters.incentiveReserveAddress][_crowdsaleAddress] = 17362500 * exponent;
  127. Approval(CrowdsaleParameters.incentiveReserveAddress, _crowdsaleAddress, 17362500 * exponent);
  128.  
  129. allowed[CrowdsaleParameters.lotteryAddress][_crowdsaleAddress] = 200000 * exponent;
  130. Approval(CrowdsaleParameters.lotteryAddress, _crowdsaleAddress, 200000 * exponent);
  131.  
  132. allowed[CrowdsaleParameters.marketingAddress][_crowdsaleAddress] = 7687500 * exponent;
  133. Approval(CrowdsaleParameters.marketingAddress, _crowdsaleAddress, 7687500 * exponent);
  134. }
  135.  
  136. /**
  137. * Get total supply of SED token
  138. *
  139. * @return total minted supply
  140. */
  141. function totalSupply() public constant returns (uint256 result) {
  142. result = _totalSupply;
  143. }
  144.  
  145. /**
  146. * Get token balance of an address
  147. *
  148. * @param _address - address to query
  149. * @return Token balance of _address
  150. */
  151. function balanceOf(address _address) public constant returns (uint256 balance) {
  152. return balances[_address];
  153. }
  154.  
  155. /**
  156. * Get token amount allocated for a transaction from _owner to _spender addresses
  157. *
  158. * @param _owner - owner address, i.e. address to transfer from
  159. * @param _spender - spender address, i.e. address to transfer to
  160. * @return Remaining amount allowed to be transferred
  161. */
  162. function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
  163. return allowed[_owner][_spender];
  164. }
  165.  
  166. /**
  167. * Send coins from sender's address to address specified in parameters
  168. *
  169. * @param _to - address to send to
  170. * @param _value - amount to send in Wei
  171. */
  172. function transfer(address _to, uint256 _value) public transfersAllowed onlyPayloadSize(2*32) returns (bool success) {
  173. checkMyVesting(msg.sender);
  174.  
  175. require(accountBalance(msg.sender) >= _value);
  176.  
  177. // Subtract from the sender
  178. // _value is never greater than balance of input validation above
  179. balances[msg.sender] -= _value;
  180.  
  181. if (vestingTimesForPools[msg.sender] > 0 && vestingTimesForPools[msg.sender] > now) {
  182. addToVesting(msg.sender, _to, vestingTimesForPools[msg.sender], _value);
  183. }
  184.  
  185. // Overflow is never possible due to input validation above
  186. balances[_to] += _value;
  187.  
  188. addIndex(_to);
  189. Transfer(msg.sender, _to, _value);
  190. return true;
  191. }
  192.  
  193. /**
  194. * Create token and credit it to target address
  195. * Created tokens need to vest (in opposite to issue method)
  196. *
  197. * @param target - address to credit new tokens to
  198. * @param mintedAmount - number of tokens to create
  199. * @param vestingTime - vesting time of new tokens
  200. */
  201. function mintToken(address target, uint256 mintedAmount, uint256 vestingTime) internal {
  202. if (vestingTime > now) {
  203. addToVesting(owner, target, vestingTime, mintedAmount);
  204. }
  205.  
  206. balances[target] += mintedAmount;
  207.  
  208. _totalSupply += mintedAmount;
  209. Issuance(mintedAmount);
  210. addIndex(target);
  211. Transfer(this, target, mintedAmount);
  212. }
  213.  
  214. function addIndex(address _address) internal {
  215. if (!addressAddedToIndex[_address]) {
  216. addressAddedToIndex[_address] = true;
  217. addressByIndex.push(_address);
  218. }
  219. }
  220.  
  221. function addVestingTime(uint256 time) internal {
  222. vestingTimes.push(time);
  223. }
  224.  
  225. function addToVesting(address from, address target, uint256 vestingTime, uint256 amount) internal {
  226. vestingBalanceOf[target][0] += amount;
  227. vestingBalanceOf[target][vestingTime] += amount;
  228. VestingTransfer(from, target, amount, vestingTime);
  229. }
  230.  
  231. /**
  232. * Allow another contract to spend some tokens on your behalf
  233. *
  234. * @param _spender - address to allocate tokens for
  235. * @param _value - number of tokens to allocate
  236. * @return True in case of success, otherwise false
  237. */
  238. function approve(address _spender, uint256 _value) public onlyPayloadSize(2*32) returns (bool success) {
  239. require(_value == 0 || allowanceUsed[msg.sender][_spender] == false);
  240.  
  241. allowed[msg.sender][_spender] = _value;
  242. allowanceUsed[msg.sender][_spender] = false;
  243. Approval(msg.sender, _spender, _value);
  244.  
  245. return true;
  246. }
  247.  
  248. /**
  249. * Approve and then communicate the approved contract in a single tx
  250. *
  251. * @param _spender - address to allocate tokens for
  252. * @param _value - number of tokens to allocate
  253. * @param _extraData - extra data to be included in data field in this transaction
  254. * @return True in case of success, otherwise false
  255. */
  256. function approveAndCall(address _spender, uint256 _value, bytes _extraData) public onlyPayloadSize(2*32) returns (bool success) {
  257. TokenRecipient spender = TokenRecipient(_spender);
  258. if (approve(_spender, _value)) {
  259. spender.receiveApproval(msg.sender, _value, this, _extraData);
  260. return true;
  261. }
  262. }
  263.  
  264. /**
  265. * A contract attempts to transfer previously allocated tokens.
  266. *
  267. * @param _to - address to transfer tokens to
  268. * @param _from - address to transfer tokens from
  269. * @param _value - number of tokens to transfer
  270. * @return True in case of success, otherwise false
  271. */
  272. function transferFrom(address _from, address _to, uint256 _value) public transfersAllowed onlyPayloadSize(3*32) returns (bool success) {
  273. checkMyVesting(_from);
  274.  
  275. // Check if the sender has enough
  276. require(accountBalance(_from) >= _value);
  277.  
  278. // Check allowed
  279. require(_value <= allowed[_from][msg.sender]);
  280.  
  281. // Subtract from the sender
  282. // _value is never greater than balance because of input validation above
  283. balances[_from] -= _value;
  284. // Add the same to the recipient
  285. // Overflow is not possible because of input validation above
  286. balances[_to] += _value;
  287.  
  288. // Deduct allocation
  289. // _value is never greater than allowed amount because of input validation above
  290. allowed[_from][msg.sender] -= _value;
  291.  
  292. if (vestingTimesForPools[_from] > 0 && vestingTimesForPools[_from] > now) {
  293. addToVesting(_from, _to, vestingTimesForPools[_from], _value);
  294. }
  295.  
  296. addIndex(_to);
  297. Transfer(msg.sender, _from, _to, _value);
  298. allowanceUsed[_from][msg.sender] = true;
  299.  
  300. return true;
  301. }
  302.  
  303. /**
  304. * Default method
  305. *
  306. * This unnamed function is called whenever someone tries to send ether to
  307. * it. Just revert transaction because there is nothing that Token can do
  308. * with incoming ether.
  309. */
  310. function() public {
  311. revert();
  312. // Prevents accidental sending of ether
  313. }
  314.  
  315. function checkMyVesting(address sender) internal {
  316. if (vestingBalanceOf[sender][0] == 0) return;
  317.  
  318. for (uint256 k = 0; k < vestingTimes.length; k++) {
  319. if (vestingTimes[k] < now) {
  320. vestingBalanceOf[sender][0] -= vestingBalanceOf[sender][vestingTimes[k]];
  321. vestingBalanceOf[sender][vestingTimes[k]] = 0;
  322. }
  323. }
  324. }
  325.  
  326. function addVestingTimesForPool(address poolAddress, uint256 vestingTime) internal {
  327. vestingTimesForPools[poolAddress] = vestingTime;
  328. }
  329.  
  330. function countAddresses() public constant returns (uint256 length) {
  331. return addressByIndex.length;
  332. }
  333.  
  334. /**
  335. * Get vested token balance of an address
  336. *
  337. * @param _address - address to query
  338. * @return balance that has vested
  339. */
  340. function accountBalance(address _address) public constant returns (uint256 balance) {
  341. return balances[_address] - vestingBalanceOf[_address][0];
  342. }
  343.  
  344. /**
  345. * Enable or disable transfers
  346. *
  347. * @param _enable - True = enable, False = disable
  348. */
  349. function toggleTransfers(bool _enable) public onlyOwner {
  350. transfersEnabled = _enable;
  351. }
  352.  
  353. /**
  354. * Destroy tokens
  355. *
  356. * @param _from - address to destroy tokens from
  357. * @param _amount - number of tokens to destroy
  358. */
  359. function destroy(address _from, uint256 _amount) public onlyPayloadSize(2*32) {
  360. checkMyVesting(msg.sender);
  361. // validate input
  362. require(msg.sender == _from || msg.sender == owner);
  363. require(accountBalance(_from) >= _amount);
  364.  
  365. // _amount is never greater than balance because of validation above
  366. balances[_from] -= _amount;
  367.  
  368. // _amount is never greater than total supply:
  369. // 1. Because of validation above, it is never greater than balances[_from]
  370. // 2. balances[_from] is never greater than total supply
  371. _totalSupply -= _amount;
  372.  
  373. Transfer(_from, this, _amount);
  374. Destruction(_amount);
  375. }
  376. }
Add Comment
Please, Sign In to add comment