Skip to content
This repository has been archived by the owner on Sep 22, 2022. It is now read-only.

Commit

Permalink
Merge branch 'master' into burnable_transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
shrugs committed Feb 20, 2018
2 parents 167a24f + 9ea4bae commit 146e3fa
Show file tree
Hide file tree
Showing 63 changed files with 1,355 additions and 902 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ We really appreciate and value contributions to OpenZeppelin. Please take 5' to

## Contribution guidelines

Smart contracts manage value and are highly vulnerable to errors and attacks. We have very strict guidelines, please make sure to review them: ["Contribution guidelines wiki entry"](https://github.com/OpenZeppelin/zeppelin-solidity/wiki/Contrbuting-guidelines).
Smart contracts manage value and are highly vulnerable to errors and attacks. We have very strict guidelines, please make sure to review them: ["Contribution guidelines wiki entry"](https://github.com/OpenZeppelin/zeppelin-solidity/wiki/Contribution-guidelines).

## Creating Pull Requests (PRs)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ If you find a security issue, please email [security@openzeppelin.org](mailto:se

Building a distributed application, protocol or organization with OpenZeppelin?

- Read documentation: https://zeppelin-solidity.readthedocs.io/en/latest/
- Read documentation: https://openzeppelin.org/api/docs/open-zeppelin.html

- Ask for help and follow progress at: https://slack.openzeppelin.org/

Expand Down
35 changes: 0 additions & 35 deletions contracts/crowdsale/CappedCrowdsale.sol

This file was deleted.

147 changes: 99 additions & 48 deletions contracts/crowdsale/Crowdsale.sol
Original file line number Diff line number Diff line change
@@ -1,107 +1,158 @@
pragma solidity ^0.4.18;

import "../token/ERC20/MintableToken.sol";
import "../token/ERC20/ERC20.sol";
import "../math/SafeMath.sol";


/**
* @title Crowdsale
* @dev Crowdsale is a base contract for managing a token crowdsale.
* Crowdsales have a start and end timestamps, where investors can make
* token purchases and the crowdsale will assign them tokens based
* on a token per ETH rate. Funds collected are forwarded to a wallet
* as they arrive. The contract requires a MintableToken that will be
* minted as contributions arrive, note that the crowdsale contract
* must be owner of the token in order to be able to mint it.
* @dev Crowdsale is a base contract for managing a token crowdsale,
* allowing investors to purchase tokens with ether. This contract implements
* such functionality in its most fundamental form and can be extended to provide additional
* functionality and/or custom behavior.
* The external interface represents the basic interface for purchasing tokens, and conform
* the base architecture for crowdsales. They are *not* intended to be modified / overriden.
* The internal interface conforms the extensible and modifiable surface of crowdsales. Override
* the methods to add functionality. Consider using 'super' where appropiate to concatenate
* behavior.
*/

contract Crowdsale {
using SafeMath for uint256;

// The token being sold
MintableToken public token;

// start and end timestamps where investments are allowed (both inclusive)
uint256 public startTime;
uint256 public endTime;
ERC20 public token;

// address where funds are collected
// Address where funds are collected
address public wallet;

// how many token units a buyer gets per wei
// How many token units a buyer gets per wei
uint256 public rate;

// amount of raised money in wei
// Amount of wei raised
uint256 public weiRaised;

/**
* event for token purchase logging
* Event for token purchase logging
* @param purchaser who paid for the tokens
* @param beneficiary who got the tokens
* @param value weis paid for purchase
* @param amount amount of tokens purchased
*/
event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);


function Crowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, address _wallet, MintableToken _token) public {
require(_startTime >= now);
require(_endTime >= _startTime);
/**
* @param _rate Number of token units a buyer gets per wei
* @param _wallet Address where collected funds will be forwarded to
* @param _token Address of the token being sold
*/
function Crowdsale(uint256 _rate, address _wallet, ERC20 _token) public {
require(_rate > 0);
require(_wallet != address(0));
require(_token != address(0));

startTime = _startTime;
endTime = _endTime;
rate = _rate;
wallet = _wallet;
token = _token;
}

// fallback function can be used to buy tokens
// -----------------------------------------
// Crowdsale external interface
// -----------------------------------------

/**
* @dev fallback function ***DO NOT OVERRIDE***
*/
function () external payable {
buyTokens(msg.sender);
}

// low level token purchase function
function buyTokens(address beneficiary) public payable {
require(beneficiary != address(0));
require(validPurchase());
/**
* @dev low level token purchase ***DO NOT OVERRIDE***
* @param _beneficiary Address performing the token purchase
*/
function buyTokens(address _beneficiary) public payable {

uint256 weiAmount = msg.value;
_preValidatePurchase(_beneficiary, weiAmount);

// calculate token amount to be created
uint256 tokens = getTokenAmount(weiAmount);
uint256 tokens = _getTokenAmount(weiAmount);

// update state
weiRaised = weiRaised.add(weiAmount);

token.mint(beneficiary, tokens);
TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
_processPurchase(_beneficiary, tokens);
TokenPurchase(msg.sender, _beneficiary, weiAmount, tokens);

_updatePurchasingState(_beneficiary, weiAmount);

_forwardFunds();
_postValidatePurchase(_beneficiary, weiAmount);
}

// -----------------------------------------
// Internal interface (extensible)
// -----------------------------------------

/**
* @dev Validation of an incoming purchase. Use require statemens to revert state when conditions are not met. Use super to concatenate validations.
* @param _beneficiary Address performing the token purchase
* @param _weiAmount Value in wei involved in the purchase
*/
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal {
require(_beneficiary != address(0));
require(_weiAmount != 0);
}

forwardFunds();
/**
* @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid conditions are not met.
* @param _beneficiary Address performing the token purchase
* @param _weiAmount Value in wei involved in the purchase
*/
function _postValidatePurchase(address _beneficiary, uint256 _weiAmount) internal {
// optional override
}

// @return true if crowdsale event has ended
function hasEnded() public view returns (bool) {
return now > endTime;
/**
* @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends its tokens.
* @param _beneficiary Address performing the token purchase
* @param _tokenAmount Number of tokens to be emitted
*/
function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal {
token.transfer(_beneficiary, _tokenAmount);
}

// Override this method to have a way to add business logic to your crowdsale when buying
function getTokenAmount(uint256 weiAmount) internal view returns(uint256) {
return weiAmount.mul(rate);
/**
* @dev Executed when a purchase has been validated and is ready to be executed. Not necessarily emits/sends tokens.
* @param _beneficiary Address receiving the tokens
* @param _tokenAmount Number of tokens to be purchased
*/
function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal {
_deliverTokens(_beneficiary, _tokenAmount);
}

// send ether to the fund collection wallet
// override to create custom fund forwarding mechanisms
function forwardFunds() internal {
wallet.transfer(msg.value);
/**
* @dev Override for extensions that require an internal state to check for validity (current user contributions, etc.)
* @param _beneficiary Address receiving the tokens
* @param _weiAmount Value in wei involved in the purchase
*/
function _updatePurchasingState(address _beneficiary, uint256 _weiAmount) internal {
// optional override
}

// @return true if the transaction can buy tokens
function validPurchase() internal view returns (bool) {
bool withinPeriod = now >= startTime && now <= endTime;
bool nonZeroPurchase = msg.value != 0;
return withinPeriod && nonZeroPurchase;
/**
* @dev Override to extend the way in which ether is converted to tokens.
* @param _weiAmount Value in wei to be converted into tokens
* @return Number of tokens that can be purchased with the specified _weiAmount
*/
function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) {
return _weiAmount.mul(rate);
}

/**
* @dev Determines how ETH is stored/forwarded on purchases.
*/
function _forwardFunds() internal {
wallet.transfer(msg.value);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
pragma solidity ^0.4.18;

import "../math/SafeMath.sol";
import "../ownership/Ownable.sol";
import "./Crowdsale.sol";

import "../../math/SafeMath.sol";
import "../../ownership/Ownable.sol";
import "../validation/TimedCrowdsale.sol";

/**
* @title FinalizableCrowdsale
* @dev Extension of Crowdsale where an owner can do extra work
* after finishing.
*/
contract FinalizableCrowdsale is Crowdsale, Ownable {
contract FinalizableCrowdsale is TimedCrowdsale, Ownable {
using SafeMath for uint256;

bool public isFinalized = false;
Expand All @@ -23,7 +22,7 @@ contract FinalizableCrowdsale is Crowdsale, Ownable {
*/
function finalize() onlyOwner public {
require(!isFinalized);
require(hasEnded());
require(hasClosed());

finalization();
Finalized();
Expand Down
35 changes: 35 additions & 0 deletions contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
pragma solidity ^0.4.18;

import "../validation/TimedCrowdsale.sol";
import "../../token/ERC20/ERC20.sol";
import "../../math/SafeMath.sol";

/**
* @title PostDeliveryCrowdsale
* @dev Crowdsale that locks tokens from withdrawal until it ends.
*/
contract PostDeliveryCrowdsale is TimedCrowdsale {
using SafeMath for uint256;

mapping(address => uint256) public balances;

/**
* @dev Overrides parent by storing balances instead of issuing tokens right away.
* @param _beneficiary Token purchaser
* @param _tokenAmount Amount of tokens purchased
*/
function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal {
balances[_beneficiary] = balances[_beneficiary].add(_tokenAmount);
}

/**
* @dev Withdraw tokens only after crowdsale ends.
*/
function withdrawTokens() public {
require(hasClosed());
uint256 amount = balances[msg.sender];
require(amount > 0);
balances[msg.sender] = 0;
_deliverTokens(msg.sender, amount);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
pragma solidity ^0.4.18;


import "../math/SafeMath.sol";
import "../../math/SafeMath.sol";
import "./FinalizableCrowdsale.sol";
import "./RefundVault.sol";
import "./utils/RefundVault.sol";


/**
Expand All @@ -21,25 +21,37 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
// refund vault used to hold funds while crowdsale is running
RefundVault public vault;

/**
* @dev Constructor, creates RefundVault.
* @param _goal Funding goal
*/
function RefundableCrowdsale(uint256 _goal) public {
require(_goal > 0);
vault = new RefundVault(wallet);
goal = _goal;
}

// if crowdsale is unsuccessful, investors can claim refunds here
/**
* @dev Investors can claim refunds here if crowdsale is unsuccessful
*/
function claimRefund() public {
require(isFinalized);
require(!goalReached());

vault.refund(msg.sender);
}

/**
* @dev Checks whether funding goal was reached.
* @return Whether funding goal was reached
*/
function goalReached() public view returns (bool) {
return weiRaised >= goal;
}

// vault finalization task, called when owner calls finalize()
/**
* @dev vault finalization task, called when owner calls finalize()
*/
function finalization() internal {
if (goalReached()) {
vault.close();
Expand All @@ -50,10 +62,10 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
super.finalization();
}

// We're overriding the fund forwarding from Crowdsale.
// In addition to sending the funds, we want to call
// the RefundVault deposit function
function forwardFunds() internal {
/**
* @dev Overrides Crowdsale fund forwarding, sending funds to vault.
*/
function _forwardFunds() internal {
vault.deposit.value(msg.value)(msg.sender);
}

Expand Down
Loading

0 comments on commit 146e3fa

Please sign in to comment.