Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve encapsulation on Crowdsales #1268

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
58 changes: 43 additions & 15 deletions contracts/crowdsale/Crowdsale.sol
Expand Up @@ -22,19 +22,16 @@ contract Crowdsale {
using SafeERC20 for IERC20;

// The token being sold
IERC20 public token;
IERC20 private token_;

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

// How many token units a buyer gets per wei.
// The rate is the conversion between wei and the smallest and indivisible token unit.
// So, if you are using a rate of 1 with a ERC20Detailed token with 3 decimals called TOK
// 1 wei will give you 1 unit, or 0.001 TOK.
uint256 public rate;
uint256 private rate_;

// Amount of wei raised
uint256 public weiRaised;
uint256 private weiRaised_;

/**
* Event for token purchase logging
Expand All @@ -52,6 +49,9 @@ contract Crowdsale {

/**
* @param _rate Number of token units a buyer gets per wei
* @dev The rate is the conversion between wei and the smallest and indivisible
* token unit. So, if you are using a rate of 1 with a ERC20Detailed token
* with 3 decimals called TOK, 1 wei will give you 1 unit, or 0.001 TOK.
* @param _wallet Address where collected funds will be forwarded to
* @param _token Address of the token being sold
*/
Expand All @@ -60,9 +60,9 @@ contract Crowdsale {
require(_wallet != address(0));
require(_token != address(0));

rate = _rate;
wallet = _wallet;
token = _token;
rate_ = _rate;
wallet_ = _wallet;
token_ = _token;
}

// -----------------------------------------
Expand All @@ -76,6 +76,34 @@ contract Crowdsale {
buyTokens(msg.sender);
}

/**
* @return the token being sold.
*/
function token() public view returns(IERC20) {
return token_;
}

/**
* @return the address where funds are collected.
*/
function wallet() public view returns(address) {
return wallet_;
}

/**
* @return the number of token units a buyer gets per wei.
*/
function rate() public view returns(uint256) {
return rate_;
}

/**
* @return the mount of wei raised.
*/
function weiRaised() public view returns (uint256) {
return weiRaised_;
}

/**
* @dev low level token purchase ***DO NOT OVERRIDE***
* @param _beneficiary Address performing the token purchase
Expand All @@ -89,7 +117,7 @@ contract Crowdsale {
uint256 tokens = _getTokenAmount(weiAmount);

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

_processPurchase(_beneficiary, tokens);
emit TokensPurchased(
Expand All @@ -113,7 +141,7 @@ contract Crowdsale {
* @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met. Use `super` in contracts that inherit from Crowdsale to extend their validations.
* Example from CappedCrowdsale.sol's _preValidatePurchase method:
* super._preValidatePurchase(_beneficiary, _weiAmount);
* require(weiRaised.add(_weiAmount) <= cap);
* require(weiRaised().add(_weiAmount) <= cap);
* @param _beneficiary Address performing the token purchase
* @param _weiAmount Value in wei involved in the purchase
*/
Expand Down Expand Up @@ -152,7 +180,7 @@ contract Crowdsale {
)
internal
{
token.safeTransfer(_beneficiary, _tokenAmount);
token_.safeTransfer(_beneficiary, _tokenAmount);
}

/**
Expand Down Expand Up @@ -191,13 +219,13 @@ contract Crowdsale {
function _getTokenAmount(uint256 _weiAmount)
internal view returns (uint256)
{
return _weiAmount.mul(rate);
return _weiAmount.mul(rate_);
}

/**
* @dev Determines how ETH is stored/forwarded on purchases.
*/
function _forwardFunds() internal {
wallet.transfer(msg.value);
wallet_.transfer(msg.value);
}
}
13 changes: 10 additions & 3 deletions contracts/crowdsale/distribution/FinalizableCrowdsale.sol
Expand Up @@ -13,22 +13,29 @@ import "../validation/TimedCrowdsale.sol";
contract FinalizableCrowdsale is Ownable, TimedCrowdsale {
using SafeMath for uint256;

bool public isFinalized = false;
bool private finalized_ = false;

event CrowdsaleFinalized();

/**
* @return true if the crowdsale is finalized, false otherwise.
*/
function finalized() public view returns(bool) {
return finalized_;
}

/**
* @dev Must be called after crowdsale ends, to do some extra finalization
* work. Calls the contract's finalization function.
*/
function finalize() public onlyOwner {
require(!isFinalized);
require(!finalized_);
require(hasClosed());

_finalization();
emit CrowdsaleFinalized();

isFinalized = true;
finalized_ = true;
}

/**
Expand Down
15 changes: 11 additions & 4 deletions contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol
Expand Up @@ -12,20 +12,27 @@ import "../../math/SafeMath.sol";
contract PostDeliveryCrowdsale is TimedCrowdsale {
using SafeMath for uint256;

mapping(address => uint256) public balances;
mapping(address => uint256) private balances_;

/**
* @dev Withdraw tokens only after crowdsale ends.
* @param _beneficiary Whose tokens will be withdrawn.
*/
function withdrawTokens(address _beneficiary) public {
require(hasClosed());
uint256 amount = balances[_beneficiary];
uint256 amount = balances_[_beneficiary];
require(amount > 0);
balances[_beneficiary] = 0;
balances_[_beneficiary] = 0;
_deliverTokens(_beneficiary, amount);
}

/**
* @return the balance of an account.
*/
function balanceOf(address _account) public view returns(uint256) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You see what I did here? :o uncle bob martin is crying.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ˜‚

return balances_[_account];
}

/**
* @dev Overrides parent by storing balances instead of issuing tokens right away.
* @param _beneficiary Token purchaser
Expand All @@ -37,7 +44,7 @@ contract PostDeliveryCrowdsale is TimedCrowdsale {
)
internal
{
balances[_beneficiary] = balances[_beneficiary].add(_tokenAmount);
balances_[_beneficiary] = balances_[_beneficiary].add(_tokenAmount);
}

}
17 changes: 12 additions & 5 deletions contracts/crowdsale/distribution/RefundableCrowdsale.sol
Expand Up @@ -15,7 +15,7 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
using SafeMath for uint256;

// minimum amount of funds to be raised in weis
uint256 public goal;
uint256 private goal_;

// refund escrow used to hold funds while crowdsale is running
RefundEscrow private escrow_;
Expand All @@ -26,16 +26,23 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
*/
constructor(uint256 _goal) public {
require(_goal > 0);
escrow_ = new RefundEscrow(wallet);
goal = _goal;
escrow_ = new RefundEscrow(wallet());
goal_ = _goal;
}

/**
* @return minimum amount of funds to be raised in wei.
*/
function goal() public view returns(uint256) {
return goal_;
}

/**
* @dev Investors can claim refunds here if crowdsale is unsuccessful
* @param _beneficiary Whose refund will be claimed.
*/
function claimRefund(address _beneficiary) public {
require(isFinalized);
require(finalized());
require(!goalReached());

escrow_.withdraw(_beneficiary);
Expand All @@ -46,7 +53,7 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
* @return Whether funding goal was reached
*/
function goalReached() public view returns (bool) {
return weiRaised >= goal;
return weiRaised() >= goal_;
}

/**
Expand Down
15 changes: 11 additions & 4 deletions contracts/crowdsale/emission/AllowanceCrowdsale.sol
Expand Up @@ -14,23 +14,30 @@ contract AllowanceCrowdsale is Crowdsale {
using SafeMath for uint256;
using SafeERC20 for IERC20;

address public tokenWallet;
address private tokenWallet_;

/**
* @dev Constructor, takes token wallet address.
* @param _tokenWallet Address holding the tokens, which has approved allowance to the crowdsale
*/
constructor(address _tokenWallet) public {
require(_tokenWallet != address(0));
tokenWallet = _tokenWallet;
tokenWallet_ = _tokenWallet;
}

/**
* @return the address of the wallet that will hold the tokens.
*/
function tokenWallet() public view returns(address) {
return tokenWallet_;
}

/**
* @dev Checks the amount of tokens left in the allowance.
* @return Amount of tokens left in the allowance
*/
function remainingTokens() public view returns (uint256) {
return token.allowance(tokenWallet, this);
return token().allowance(tokenWallet_, this);
}

/**
Expand All @@ -44,6 +51,6 @@ contract AllowanceCrowdsale is Crowdsale {
)
internal
{
token.safeTransferFrom(tokenWallet, _beneficiary, _tokenAmount);
token().safeTransferFrom(tokenWallet_, _beneficiary, _tokenAmount);
}
}
3 changes: 2 additions & 1 deletion contracts/crowdsale/emission/MintedCrowdsale.sol
Expand Up @@ -23,6 +23,7 @@ contract MintedCrowdsale is Crowdsale {
internal
{
// Potentially dangerous assumption about the type of the token.
require(ERC20Mintable(address(token)).mint(_beneficiary, _tokenAmount));
require(
ERC20Mintable(address(token())).mint(_beneficiary, _tokenAmount));
}
}
26 changes: 20 additions & 6 deletions contracts/crowdsale/price/IncreasingPriceCrowdsale.sol
Expand Up @@ -13,8 +13,8 @@ import "../../math/SafeMath.sol";
contract IncreasingPriceCrowdsale is TimedCrowdsale {
using SafeMath for uint256;

uint256 public initialRate;
uint256 public finalRate;
uint256 private initialRate_;
uint256 private finalRate_;

/**
* @dev Constructor, takes initial and final rates of tokens received per wei contributed.
Expand All @@ -24,8 +24,22 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale {
constructor(uint256 _initialRate, uint256 _finalRate) public {
require(_finalRate > 0);
require(_initialRate >= _finalRate);
initialRate = _initialRate;
finalRate = _finalRate;
initialRate_ = _initialRate;
finalRate_ = _finalRate;
}

/**
* @return the initial rate of the crowdsale.
*/
function initialRate() public view returns(uint256) {
return initialRate_;
}

/**
* @return the final rate of the crowdsale.
*/
function finalRate() public view returns (uint256) {
return finalRate_;
}

/**
Expand All @@ -37,8 +51,8 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale {
// solium-disable-next-line security/no-block-members
uint256 elapsedTime = block.timestamp.sub(openingTime);
uint256 timeRange = closingTime.sub(openingTime);
uint256 rateRange = initialRate.sub(finalRate);
return initialRate.sub(elapsedTime.mul(rateRange).div(timeRange));
uint256 rateRange = initialRate_.sub(finalRate_);
return initialRate_.sub(elapsedTime.mul(rateRange).div(timeRange));
}

/**
Expand Down
15 changes: 11 additions & 4 deletions contracts/crowdsale/validation/CappedCrowdsale.sol
Expand Up @@ -11,23 +11,30 @@ import "../Crowdsale.sol";
contract CappedCrowdsale is Crowdsale {
using SafeMath for uint256;

uint256 public cap;
uint256 private cap_;

/**
* @dev Constructor, takes maximum amount of wei accepted in the crowdsale.
* @param _cap Max amount of wei to be contributed
*/
constructor(uint256 _cap) public {
require(_cap > 0);
cap = _cap;
cap_ = _cap;
}

/**
* @return the cap of the crowdsale.
*/
function cap() public view returns(uint256) {
return cap_;
}

/**
* @dev Checks whether the cap has been reached.
* @return Whether the cap was reached
*/
function capReached() public view returns (bool) {
return weiRaised >= cap;
return weiRaised() >= cap_;
}

/**
Expand All @@ -42,7 +49,7 @@ contract CappedCrowdsale is Crowdsale {
internal
{
super._preValidatePurchase(_beneficiary, _weiAmount);
require(weiRaised.add(_weiAmount) <= cap);
require(weiRaised().add(_weiAmount) <= cap_);
}

}