1# IndividuallyCappedCrowdsale 2# Contributors: Binod Nirvan 3# This file is released under Apache 2.0 license. 4# @dev Crowdsale with a limit for total contributions. 5# Ported from Open Zeppelin 6# https://github.com/OpenZeppelin 7# 8# See https://github.com/OpenZeppelin 9# Open Zeppelin tests ported: Crowdsale.test.js 10 11 12#@dev ERC20/223 Features referenced by this contract 13contract TokenContract: 14 def transfer(_to: address, _value: uint256) -> bool: modifying 15 16# Event for token purchase logging 17# @param _purchaser who paid for the tokens 18# @param _beneficiary who got the tokens 19# @param _value weis paid for purchase 20# @param _amount amount of tokens purchased 21TokenPurchase: event({_purchaser: indexed(address), _beneficiary: indexed(address), _value: uint256(wei), _amount: uint256}) 22 23# The token being sold 24token: public(address) 25 26#Address where funds are collected 27wallet: public(address) 28 29# How many token units a buyer gets per wei. 30# The rate is the conversion between wei and the smallest and indivisible token unit. 31# So, if you are using a rate of 1 with a DetailedERC20 token with 3 decimals called TOK 32# 1 wei will give you 1 unit, or 0.001 TOK. 33rate: public(uint256) 34 35#Amount of wei raised 36weiRaised: public(uint256(wei)) 37 38@public 39def __init__(_rate: uint256, _wallet: address, _token: address): 40 """ 41 @dev Initializes this contract 42 @param _rate Number of token units a buyer gets per wei 43 @param _wallet Address where collected funds will be forwarded to 44 @param _token Address of the token being sold 45 """ 46 47 assert _rate > 0, "Invalid value supplied for the parameter \"_rate\"." 48 assert _wallet != ZERO_ADDRESS, "Invalid wallet address." 49 assert _token != ZERO_ADDRESS, "Invalid token address." 50 51 self.rate = _rate 52 self.wallet = _wallet 53 self.token = _token 54 55@private 56@constant 57def getTokenAmount(_weiAmount: uint256) -> uint256: 58 return _weiAmount * self.rate 59 60 61@private 62def processTransaction(_sender: address, _beneficiary: address, _weiAmount: uint256(wei)): 63 #pre validate 64 assert _beneficiary != ZERO_ADDRESS, "Invalid address." 65 assert _weiAmount != 0, "Invalid amount received." 66 67 #calculate the number of tokens for the Ether contribution. 68 tokens: uint256 = self.getTokenAmount(as_unitless_number(_weiAmount)) 69 70 self.weiRaised += _weiAmount 71 72 #process purchase 73 assert TokenContract(self.token).transfer(_beneficiary, tokens), "Could not forward funds due to an unknown error." 74 log.TokenPurchase(_sender, _beneficiary, _weiAmount, tokens) 75 76 #forward funds to the receiving wallet address. 77 send(self.wallet, _weiAmount) 78 79 #post validate 80 81@public 82@payable 83def buyTokens(_beneficiary: address): 84 self.processTransaction(msg.sender, _beneficiary, msg.value) 85 86@public 87@payable 88def __default__(): 89 self.processTransaction(msg.sender, msg.sender, msg.value) 90