Advertisement
Guest User

Crowdsale Contract of OpenZeppelin

a guest
Dec 21st, 2017
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.09 KB | None | 0 0
  1. pragma solidity ^0.4.18;
  2.  
  3.  
  4. /**
  5. * @title ERC20Basic
  6. * @dev Simpler version of ERC20 interface
  7. * @dev see https://github.com/ethereum/EIPs/issues/179
  8. */
  9. contract ERC20Basic {
  10. uint256 public totalSupply;
  11. function balanceOf(address who) public view returns (uint256);
  12. function transfer(address to, uint256 value) public returns (bool);
  13. event Transfer(address indexed from, address indexed to, uint256 value);
  14. }
  15.  
  16.  
  17.  
  18. /**
  19. * @title Ownable
  20. * @dev The Ownable contract has an owner address, and provides basic authorization control
  21. * functions, this simplifies the implementation of "user permissions".
  22. */
  23. contract Ownable {
  24. address public owner;
  25.  
  26.  
  27. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
  28.  
  29.  
  30. /**
  31. * @dev The Ownable constructor sets the original `owner` of the contract to the sender
  32. * account.
  33. */
  34. function Ownable() public {
  35. owner = msg.sender;
  36. }
  37.  
  38.  
  39. /**
  40. * @dev Throws if called by any account other than the owner.
  41. */
  42. modifier onlyOwner() {
  43. require(msg.sender == owner);
  44. _;
  45. }
  46.  
  47.  
  48. /**
  49. * @dev Allows the current owner to transfer control of the contract to a newOwner.
  50. * @param newOwner The address to transfer ownership to.
  51. */
  52. function transferOwnership(address newOwner) public onlyOwner {
  53. require(newOwner != address(0));
  54. OwnershipTransferred(owner, newOwner);
  55. owner = newOwner;
  56. }
  57.  
  58. }
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66. /**
  67. * @title SafeMath
  68. * @dev Math operations with safety checks that throw on error
  69. */
  70. library SafeMath {
  71. function mul(uint256 a, uint256 b) internal pure returns (uint256) {
  72. if (a == 0) {
  73. return 0;
  74. }
  75. uint256 c = a * b;
  76. assert(c / a == b);
  77. return c;
  78. }
  79.  
  80. function div(uint256 a, uint256 b) internal pure returns (uint256) {
  81. // assert(b > 0); // Solidity automatically throws when dividing by 0
  82. uint256 c = a / b;
  83. // assert(a == b * c + a % b); // There is no case in which this doesn't hold
  84. return c;
  85. }
  86.  
  87. function sub(uint256 a, uint256 b) internal pure returns (uint256) {
  88. assert(b <= a);
  89. return a - b;
  90. }
  91.  
  92. function add(uint256 a, uint256 b) internal pure returns (uint256) {
  93. uint256 c = a + b;
  94. assert(c >= a);
  95. return c;
  96. }
  97. }
  98.  
  99. /**
  100. * @title Crowdsale
  101. * @dev Crowdsale is a base contract for managing a token crowdsale.
  102. * Crowdsales have a start and end timestamps, where investors can make
  103. * token purchases and the crowdsale will assign them tokens based
  104. * on a token per ETH rate. Funds collected are forwarded to a wallet
  105. * as they arrive.
  106. */
  107. contract Crowdsale {
  108. using SafeMath for uint256;
  109.  
  110. // The token being sold
  111. MintableToken public token;
  112.  
  113. // start and end timestamps where investments are allowed (both inclusive)
  114. uint256 public startTime;
  115. uint256 public endTime;
  116.  
  117. // address where funds are collected
  118. address public wallet;
  119.  
  120. // how many token units a buyer gets per wei
  121. uint256 public rate;
  122.  
  123. // amount of raised money in wei
  124. uint256 public weiRaised;
  125.  
  126. /**
  127. * event for token purchase logging
  128. * @param purchaser who paid for the tokens
  129. * @param beneficiary who got the tokens
  130. * @param value weis paid for purchase
  131. * @param amount amount of tokens purchased
  132. */
  133. event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
  134.  
  135.  
  136. function Crowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, address _wallet) public {
  137. require(_startTime >= now);
  138. require(_endTime >= _startTime);
  139. require(_rate > 0);
  140. require(_wallet != address(0));
  141.  
  142. token = createTokenContract();
  143. startTime = _startTime;
  144. endTime = _endTime;
  145. rate = _rate;
  146. wallet = _wallet;
  147. }
  148.  
  149. // creates the token to be sold.
  150. // override this method to have crowdsale of a specific mintable token.
  151. function createTokenContract() internal returns (MintableToken) {
  152. return new MintableToken();
  153. }
  154.  
  155.  
  156. // fallback function can be used to buy tokens
  157. function () external payable {
  158. buyTokens(msg.sender);
  159. }
  160.  
  161. // low level token purchase function
  162. function buyTokens(address beneficiary) public payable {
  163. require(beneficiary != address(0));
  164. require(validPurchase());
  165.  
  166. uint256 weiAmount = msg.value;
  167.  
  168. // calculate token amount to be created
  169. uint256 tokens = weiAmount.mul(rate);
  170.  
  171. // update state
  172. weiRaised = weiRaised.add(weiAmount);
  173.  
  174. token.mint(beneficiary, tokens);
  175. TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
  176.  
  177. forwardFunds();
  178. }
  179.  
  180. // send ether to the fund collection wallet
  181. // override to create custom fund forwarding mechanisms
  182. function forwardFunds() internal {
  183. wallet.transfer(msg.value);
  184. }
  185.  
  186. // @return true if the transaction can buy tokens
  187. function validPurchase() internal view returns (bool) {
  188. bool withinPeriod = now >= startTime && now <= endTime;
  189. bool nonZeroPurchase = msg.value != 0;
  190. return withinPeriod && nonZeroPurchase;
  191. }
  192.  
  193. // @return true if crowdsale event has ended
  194. function hasEnded() public view returns (bool) {
  195. return now > endTime;
  196. }
  197.  
  198.  
  199. }
  200.  
  201. /**
  202. * @title CappedCrowdsale
  203. * @dev Extension of Crowdsale with a max amount of funds raised
  204. */
  205. contract CappedCrowdsale is Crowdsale {
  206. using SafeMath for uint256;
  207.  
  208. uint256 public cap;
  209.  
  210. function CappedCrowdsale(uint256 _cap) public {
  211. require(_cap > 0);
  212. cap = _cap;
  213. }
  214.  
  215. // overriding Crowdsale#validPurchase to add extra cap logic
  216. // @return true if investors can buy at the moment
  217. function validPurchase() internal view returns (bool) {
  218. bool withinCap = weiRaised.add(msg.value) <= cap;
  219. return super.validPurchase() && withinCap;
  220. }
  221.  
  222. // overriding Crowdsale#hasEnded to add cap logic
  223. // @return true if crowdsale event has ended
  224. function hasEnded() public view returns (bool) {
  225. bool capReached = weiRaised >= cap;
  226. return super.hasEnded() || capReached;
  227. }
  228.  
  229. }
  230.  
  231. /**
  232. * @title FinalizableCrowdsale
  233. * @dev Extension of Crowdsale where an owner can do extra work
  234. * after finishing.
  235. */
  236. contract FinalizableCrowdsale is Crowdsale, Ownable {
  237. using SafeMath for uint256;
  238.  
  239. bool public isFinalized = false;
  240.  
  241. event Finalized();
  242.  
  243. /**
  244. * @dev Must be called after crowdsale ends, to do some extra finalization
  245. * work. Calls the contract's finalization function.
  246. */
  247. function finalize() onlyOwner public {
  248. require(!isFinalized);
  249. require(hasEnded());
  250.  
  251. finalization();
  252. Finalized();
  253.  
  254. isFinalized = true;
  255. }
  256.  
  257. /**
  258. * @dev Can be overridden to add finalization logic. The overriding function
  259. * should call super.finalization() to ensure the chain of finalization is
  260. * executed entirely.
  261. */
  262. function finalization() internal {
  263. }
  264. }
  265.  
  266. /**
  267. * @title RefundVault
  268. * @dev This contract is used for storing funds while a crowdsale
  269. * is in progress. Supports refunding the money if crowdsale fails,
  270. * and forwarding it if crowdsale is successful.
  271. */
  272. contract RefundVault is Ownable {
  273. using SafeMath for uint256;
  274.  
  275. enum State { Active, Refunding, Closed }
  276.  
  277. mapping (address => uint256) public deposited;
  278. address public wallet;
  279. State public state;
  280.  
  281. event Closed();
  282. event RefundsEnabled();
  283. event Refunded(address indexed beneficiary, uint256 weiAmount);
  284.  
  285. function RefundVault(address _wallet) public {
  286. require(_wallet != address(0));
  287. wallet = _wallet;
  288. state = State.Active;
  289. }
  290.  
  291. function deposit(address investor) onlyOwner public payable {
  292. require(state == State.Active);
  293. deposited[investor] = deposited[investor].add(msg.value);
  294. }
  295.  
  296. function close() onlyOwner public {
  297. require(state == State.Active);
  298. state = State.Closed;
  299. Closed();
  300. wallet.transfer(this.balance);
  301. }
  302.  
  303. function enableRefunds() onlyOwner public {
  304. require(state == State.Active);
  305. state = State.Refunding;
  306. RefundsEnabled();
  307. }
  308.  
  309. function refund(address investor) public {
  310. require(state == State.Refunding);
  311. uint256 depositedValue = deposited[investor];
  312. deposited[investor] = 0;
  313. investor.transfer(depositedValue);
  314. Refunded(investor, depositedValue);
  315. }
  316. }
  317.  
  318. /**
  319. * @title RefundableCrowdsale
  320. * @dev Extension of Crowdsale contract that adds a funding goal, and
  321. * the possibility of users getting a refund if goal is not met.
  322. * Uses a RefundVault as the crowdsale's vault.
  323. */
  324. contract RefundableCrowdsale is FinalizableCrowdsale {
  325. using SafeMath for uint256;
  326.  
  327. // minimum amount of funds to be raised in weis
  328. uint256 public goal;
  329.  
  330. // refund vault used to hold funds while crowdsale is running
  331. RefundVault public vault;
  332.  
  333. function RefundableCrowdsale(uint256 _goal) public {
  334. require(_goal > 0);
  335. vault = new RefundVault(wallet);
  336. goal = _goal;
  337. }
  338.  
  339. // We're overriding the fund forwarding from Crowdsale.
  340. // In addition to sending the funds, we want to call
  341. // the RefundVault deposit function
  342. function forwardFunds() internal {
  343. vault.deposit.value(msg.value)(msg.sender);
  344. }
  345.  
  346. // if crowdsale is unsuccessful, investors can claim refunds here
  347. function claimRefund() public {
  348. require(isFinalized);
  349. require(!goalReached());
  350.  
  351. vault.refund(msg.sender);
  352. }
  353.  
  354. // vault finalization task, called when owner calls finalize()
  355. function finalization() internal {
  356. if (goalReached()) {
  357. vault.close();
  358. } else {
  359. vault.enableRefunds();
  360. }
  361.  
  362. super.finalization();
  363. }
  364.  
  365. function goalReached() public view returns (bool) {
  366. return weiRaised >= goal;
  367. }
  368.  
  369. }
  370.  
  371. /**
  372. * @title Basic token
  373. * @dev Basic version of StandardToken, with no allowances.
  374. */
  375. contract BasicToken is ERC20Basic {
  376. using SafeMath for uint256;
  377.  
  378. mapping(address => uint256) balances;
  379.  
  380. /**
  381. * @dev transfer token for a specified address
  382. * @param _to The address to transfer to.
  383. * @param _value The amount to be transferred.
  384. */
  385. function transfer(address _to, uint256 _value) public returns (bool) {
  386. require(_to != address(0));
  387. require(_value <= balances[msg.sender]);
  388.  
  389. // SafeMath.sub will throw if there is not enough balance.
  390. balances[msg.sender] = balances[msg.sender].sub(_value);
  391. balances[_to] = balances[_to].add(_value);
  392. Transfer(msg.sender, _to, _value);
  393. return true;
  394. }
  395.  
  396. /**
  397. * @dev Gets the balance of the specified address.
  398. * @param _owner The address to query the the balance of.
  399. * @return An uint256 representing the amount owned by the passed address.
  400. */
  401. function balanceOf(address _owner) public view returns (uint256 balance) {
  402. return balances[_owner];
  403. }
  404.  
  405. }
  406.  
  407. /**
  408. * @title ERC20 interface
  409. * @dev see https://github.com/ethereum/EIPs/issues/20
  410. */
  411. contract ERC20 is ERC20Basic {
  412. function allowance(address owner, address spender) public view returns (uint256);
  413. function transferFrom(address from, address to, uint256 value) public returns (bool);
  414. function approve(address spender, uint256 value) public returns (bool);
  415. event Approval(address indexed owner, address indexed spender, uint256 value);
  416. }
  417.  
  418. /**
  419. * @title Standard ERC20 token
  420. *
  421. * @dev Implementation of the basic standard token.
  422. * @dev https://github.com/ethereum/EIPs/issues/20
  423. * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
  424. */
  425. contract StandardToken is ERC20, BasicToken {
  426.  
  427. mapping (address => mapping (address => uint256)) internal allowed;
  428.  
  429.  
  430. /**
  431. * @dev Transfer tokens from one address to another
  432. * @param _from address The address which you want to send tokens from
  433. * @param _to address The address which you want to transfer to
  434. * @param _value uint256 the amount of tokens to be transferred
  435. */
  436. function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
  437. require(_to != address(0));
  438. require(_value <= balances[_from]);
  439. require(_value <= allowed[_from][msg.sender]);
  440.  
  441. balances[_from] = balances[_from].sub(_value);
  442. balances[_to] = balances[_to].add(_value);
  443. allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
  444. Transfer(_from, _to, _value);
  445. return true;
  446. }
  447.  
  448. /**
  449. * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
  450. *
  451. * Beware that changing an allowance with this method brings the risk that someone may use both the old
  452. * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
  453. * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
  454. * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
  455. * @param _spender The address which will spend the funds.
  456. * @param _value The amount of tokens to be spent.
  457. */
  458. function approve(address _spender, uint256 _value) public returns (bool) {
  459. allowed[msg.sender][_spender] = _value;
  460. Approval(msg.sender, _spender, _value);
  461. return true;
  462. }
  463.  
  464. /**
  465. * @dev Function to check the amount of tokens that an owner allowed to a spender.
  466. * @param _owner address The address which owns the funds.
  467. * @param _spender address The address which will spend the funds.
  468. * @return A uint256 specifying the amount of tokens still available for the spender.
  469. */
  470. function allowance(address _owner, address _spender) public view returns (uint256) {
  471. return allowed[_owner][_spender];
  472. }
  473.  
  474. /**
  475. * approve should be called when allowed[_spender] == 0. To increment
  476. * allowed value is better to use this function to avoid 2 calls (and wait until
  477. * the first transaction is mined)
  478. * From MonolithDAO Token.sol
  479. */
  480. function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
  481. allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
  482. Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
  483. return true;
  484. }
  485.  
  486. function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
  487. uint oldValue = allowed[msg.sender][_spender];
  488. if (_subtractedValue > oldValue) {
  489. allowed[msg.sender][_spender] = 0;
  490. } else {
  491. allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
  492. }
  493. Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
  494. return true;
  495. }
  496.  
  497. }
  498.  
  499. /**
  500. * @title Mintable token
  501. * @dev Simple ERC20 Token example, with mintable token creation
  502. * @dev Issue: * https://github.com/OpenZeppelin/zeppelin-solidity/issues/120
  503. * Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
  504. */
  505.  
  506. contract MintableToken is StandardToken, Ownable {
  507. event Mint(address indexed to, uint256 amount);
  508. event MintFinished();
  509.  
  510. bool public mintingFinished = false;
  511.  
  512.  
  513. modifier canMint() {
  514. require(!mintingFinished);
  515. _;
  516. }
  517.  
  518. /**
  519. * @dev Function to mint tokens
  520. * @param _to The address that will receive the minted tokens.
  521. * @param _amount The amount of tokens to mint.
  522. * @return A boolean that indicates if the operation was successful.
  523. */
  524. function mint(address _to, uint256 _amount) onlyOwner canMint public returns (bool) {
  525. totalSupply = totalSupply.add(_amount);
  526. balances[_to] = balances[_to].add(_amount);
  527. Mint(_to, _amount);
  528. Transfer(address(0), _to, _amount);
  529. return true;
  530. }
  531.  
  532. /**
  533. * @dev Function to stop minting new tokens.
  534. * @return True if the operation was successful.
  535. */
  536. function finishMinting() onlyOwner canMint public returns (bool) {
  537. mintingFinished = true;
  538. MintFinished();
  539. return true;
  540. }
  541. }
  542.  
  543. /**
  544. * @title SampleCrowdsaleToken
  545. * @dev Very simple ERC20 Token that can be minted.
  546. * It is meant to be used in a crowdsale contract.
  547. */
  548. contract SampleCrowdsaleToken is MintableToken {
  549.  
  550. string public constant name = "Sample Crowdsale Token";
  551. string public constant symbol = "SCT";
  552. uint8 public constant decimals = 2;
  553.  
  554. }
  555.  
  556. /**
  557. * @title SampleCrowdsale
  558. * @dev This is an example of a fully fledged crowdsale.
  559. * The way to add new features to a base crowdsale is by multiple inheritance.
  560. * In this example we are providing following extensions:
  561. * CappedCrowdsale - sets a max boundary for raised funds
  562. * RefundableCrowdsale - set a min goal to be reached and returns funds if it's not met
  563. *
  564. * After adding multiple features it's good practice to run integration tests
  565. * to ensure that subcontracts works together as intended.
  566. */
  567. contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale {
  568.  
  569. function SampleCrowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, uint256 _goal, uint256 _cap, address _wallet) public
  570. CappedCrowdsale(_cap)
  571. FinalizableCrowdsale()
  572. RefundableCrowdsale(_goal)
  573. Crowdsale(_startTime, _endTime, _rate, _wallet)
  574. {
  575. //As goal needs to be met for a successful crowdsale
  576. //the value needs to less or equal than a cap which is limit for accepted funds
  577. require(_goal <= _cap);
  578. }
  579.  
  580. function createTokenContract() internal returns (MintableToken) {
  581. return new SampleCrowdsaleToken();
  582. }
  583.  
  584. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement