Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions contracts/interfaces/ISTO.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
pragma solidity ^0.4.24;

/**
* @title Interface to be implemented by all STO modules
*/
interface ISTO {
/**
* @notice Returns the total no. of tokens sold
*/
function getTokensSold() external view returns (uint256);
}
47 changes: 14 additions & 33 deletions contracts/modules/STO/CappedSTO.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
pragma solidity ^0.4.24;

import "./ISTO.sol";
import "./STO.sol";
import "../../interfaces/ISecurityToken.sol";
import "openzeppelin-solidity/contracts/ReentrancyGuard.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";

/**
* @title STO module for standard capped crowdsale
*/
contract CappedSTO is ISTO, ReentrancyGuard {
contract CappedSTO is STO, ReentrancyGuard {
using SafeMath for uint256;

// Determine whether users can invest on behalf of a beneficiary
Expand Down Expand Up @@ -51,7 +51,7 @@ contract CappedSTO is ISTO, ReentrancyGuard {
* @param _startTime Unix timestamp at which offering get started
* @param _endTime Unix timestamp at which offering get ended
* @param _cap Maximum No. of token base units for sale
* @param _rate Token units a buyer gets multiplied by 10^18 per wei / base unit of POLY
* @param _rate Token units a buyer gets multiplied by 10^18 per wei / base unit of POLY
* @param _fundRaiseTypes Type of currency used to collect the funds
* @param _fundsReceiver Ethereum account address to hold the funds
*/
Expand Down Expand Up @@ -115,7 +115,6 @@ contract CappedSTO is ISTO, ReentrancyGuard {
weiAmount = weiAmount.sub(refund);

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

/**
Expand All @@ -127,7 +126,6 @@ contract CappedSTO is ISTO, ReentrancyGuard {
require(fundRaiseTypes[uint8(FundRaiseType.POLY)], "Mode of investment is not POLY");
uint256 refund = _processTx(msg.sender, _investedPOLY);
_forwardPoly(msg.sender, wallet, _investedPOLY.sub(refund));
_postValidatePurchase(msg.sender, _investedPOLY.sub(refund));
}

/**
Expand Down Expand Up @@ -161,7 +159,7 @@ contract CappedSTO is ISTO, ReentrancyGuard {
* @return Token units a buyer gets(multiplied by 10^18) per wei / base unit of POLY
* @return Amount of funds raised
* @return Number of individual investors this STO have.
* @return Amount of tokens get sold.
* @return Amount of tokens get sold.
* @return Boolean value to justify whether the fund raise type is POLY or not, i.e true for POLY.
*/
function getSTODetails() public view returns(uint256, uint256, uint256, uint256, uint256, uint256, uint256, bool) {
Expand Down Expand Up @@ -203,8 +201,6 @@ contract CappedSTO is ISTO, ReentrancyGuard {

_processPurchase(_beneficiary, tokens);
emit TokenPurchase(msg.sender, _beneficiary, _investedAmount, tokens);

_updatePurchasingState(_beneficiary, _investedAmount);
}

/**
Expand All @@ -216,21 +212,10 @@ contract CappedSTO is ISTO, ReentrancyGuard {
function _preValidatePurchase(address _beneficiary, uint256 _investedAmount) internal view {
require(_beneficiary != address(0), "Beneficiary address should not be 0x");
require(_investedAmount != 0, "Amount invested should not be equal to 0");
uint256 tokens;
(tokens, ) = _getTokenAmount(_investedAmount);
require(totalTokensSold.add(tokens) <= cap, "Investment more than cap is not allowed");
/*solium-disable-next-line security/no-block-members*/
require(now >= startTime && now <= endTime, "Offering is closed/Not yet started");
}

/**
* @notice Validation of an executed purchase.
Observe state and use revert statements to undo rollback when valid conditions are not met.
*/
function _postValidatePurchase(address /*_beneficiary*/, uint256 /*_investedAmount*/) internal pure {
// optional override
}

/**
* @notice Source of tokens.
Override this method to modify the way in which the crowdsale ultimately gets and sends its tokens.
Expand All @@ -255,27 +240,23 @@ contract CappedSTO is ISTO, ReentrancyGuard {
_deliverTokens(_beneficiary, _tokenAmount);
}

/**
* @notice Overrides for extensions that require an internal state to check for validity
(current user contributions, etc.)
*/
function _updatePurchasingState(address /*_beneficiary*/, uint256 /*_investedAmount*/) internal pure {
// optional override
}

/**
* @notice Overrides to extend the way in which ether is converted to tokens.
* @param _investedAmount Value in wei to be converted into tokens
* @return Number of tokens that can be purchased with the specified _investedAmount
* @return Remaining amount that should be refunded to the investor
*/
function _getTokenAmount(uint256 _investedAmount) internal view returns (uint256 _tokens, uint256 _refund) {
_tokens = _investedAmount.mul(rate);
_tokens = _tokens.div(uint256(10) ** 18);
function _getTokenAmount(uint256 _investedAmount) internal view returns (uint256 tokens, uint256 refund) {
tokens = _investedAmount.mul(rate);
tokens = tokens.div(uint256(10) ** 18);
if (totalTokensSold.add(tokens) > cap) {
tokens = cap.sub(totalTokensSold);
}
uint256 granularity = ISecurityToken(securityToken).granularity();
_tokens = _tokens.div(granularity);
_tokens = _tokens.mul(granularity);
_refund = _investedAmount.sub((_tokens.mul(uint256(10) ** 18)).div(rate));
tokens = tokens.div(granularity);
tokens = tokens.mul(granularity);
require(tokens > 0, "Cap reached");
refund = _investedAmount.sub((tokens.mul(uint256(10) ** 18)).div(rate));
}

/**
Expand Down
4 changes: 2 additions & 2 deletions contracts/modules/STO/DummySTO.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
pragma solidity ^0.4.24;

import "./ISTO.sol";
import "./STO.sol";
import "../../interfaces/ISecurityToken.sol";

/**
* @title STO module for sample implementation of a different crowdsale module
*/
contract DummySTO is ISTO {
contract DummySTO is STO {

bytes32 public constant ADMIN = "ADMIN";

Expand Down
4 changes: 2 additions & 2 deletions contracts/modules/STO/PreSaleSTO.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
pragma solidity ^0.4.24;

import "./ISTO.sol";
import "./STO.sol";
import "../../interfaces/ISecurityToken.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";

/**
* @title STO module for private presales
*/
contract PreSaleSTO is ISTO {
contract PreSaleSTO is STO {
using SafeMath for uint256;

bytes32 public constant PRE_SALE_ADMIN = "PRE_SALE_ADMIN";
Expand Down
14 changes: 5 additions & 9 deletions contracts/modules/STO/ISTO.sol → contracts/modules/STO/STO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ pragma solidity ^0.4.24;
import "../../Pausable.sol";
import "../Module.sol";
import "../../interfaces/IERC20.sol";
import "./ISTOStorage.sol";
import "../../interfaces/ISTO.sol";
import "./STOStorage.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";

/**
* @title Interface to be implemented by all STO modules
*/
contract ISTO is ISTOStorage, Module, Pausable {
contract STO is ISTO, STOStorage, Module, Pausable {
using SafeMath for uint256;

enum FundRaiseType { ETH, POLY, SC }

// Event
event SetFundRaiseTypes(FundRaiseType[] _fundRaiseTypes);

Expand All @@ -36,11 +37,6 @@ contract ISTO is ISTOStorage, Module, Pausable {
return fundsRaised[uint8(_fundRaiseType)];
}

/**
* @notice Returns the total no. of tokens sold
*/
function getTokensSold() public view returns (uint256);

/**
* @notice Pause (overridden function)
*/
Expand All @@ -59,7 +55,7 @@ contract ISTO is ISTOStorage, Module, Pausable {

function _setFundRaiseType(FundRaiseType[] _fundRaiseTypes) internal {
// FundRaiseType[] parameter type ensures only valid values for _fundRaiseTypes
require(_fundRaiseTypes.length > 0, "Raise type is not specified");
require(_fundRaiseTypes.length > 0 && _fundRaiseTypes.length <= 3, "Raise type is not specified");
fundRaiseTypes[uint8(FundRaiseType.ETH)] = false;
fundRaiseTypes[uint8(FundRaiseType.POLY)] = false;
fundRaiseTypes[uint8(FundRaiseType.SC)] = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
pragma solidity ^0.4.24;

/**
* @title Storage layout for the ISTO contract
* @title Storage layout for the STO contract
*/
contract ISTOStorage {
contract STOStorage {

mapping (uint8 => bool) public fundRaiseTypes;
mapping (uint8 => uint256) public fundsRaised;
Expand All @@ -21,4 +21,4 @@ contract ISTOStorage {
// Final amount of tokens sold
uint256 public totalTokensSold;

}
}
32 changes: 16 additions & 16 deletions contracts/modules/STO/USDTieredSTO.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pragma solidity ^0.4.24;

import "./ISTO.sol";
import "./STO.sol";
import "../../interfaces/ISecurityToken.sol";
import "../../interfaces/IOracle.sol";
import "../../RegistryUpdater.sol";
Expand All @@ -12,7 +12,7 @@ import "../../storage/USDTieredSTOStorage.sol";
/**
* @title STO module for standard capped crowdsale
*/
contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
using SafeMath for uint256;

string public constant POLY_ORACLE = "PolyUsdOracle";
Expand Down Expand Up @@ -262,7 +262,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
}
usdTokens = _usdTokens;
for(i = 0; i < _usdTokens.length; i++) {
require(_usdTokens[i] != address(0), "Invalid USD token");
require(_usdTokens[i] != address(0) && _usdTokens[i] != address(polyToken), "Invalid USD token");
usdTokenEnabled[_usdTokens[i]] = true;
}
emit SetAddresses(wallet, reserveWallet, _usdTokens);
Expand All @@ -276,7 +276,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* @notice Finalizes the STO and mint remaining tokens to reserve address
* @notice Reserve address must be whitelisted to successfully finalize
*/
function finalize() public onlyOwner {
function finalize() external onlyOwner {
require(!isFinalized, "STO is already finalized");
isFinalized = true;
uint256 tempReturned;
Expand All @@ -301,7 +301,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* @param _investors Array of investor addresses to modify
* @param _accredited Array of bools specifying accreditation status
*/
function changeAccredited(address[] _investors, bool[] _accredited) public onlyOwner {
function changeAccredited(address[] _investors, bool[] _accredited) external onlyOwner {
require(_investors.length == _accredited.length, "Array length mismatch");
for (uint256 i = 0; i < _investors.length; i++) {
if (_accredited[i]) {
Expand All @@ -319,7 +319,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* @param _investors Array of investor addresses to modify
* @param _nonAccreditedLimit Array of uints specifying non-accredited limits
*/
function changeNonAccreditedLimit(address[] _investors, uint256[] _nonAccreditedLimit) public onlyOwner {
function changeNonAccreditedLimit(address[] _investors, uint256[] _nonAccreditedLimit) external onlyOwner {
//nonAccreditedLimitUSDOverride
require(_investors.length == _nonAccreditedLimit.length, "Array length mismatch");
for (uint256 i = 0; i < _investors.length; i++) {
Expand Down Expand Up @@ -357,7 +357,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* @notice Function to set allowBeneficialInvestments (allow beneficiary to be different to funder)
* @param _allowBeneficialInvestments Boolean to allow or disallow beneficial investments
*/
function changeAllowBeneficialInvestments(bool _allowBeneficialInvestments) public onlyOwner {
function changeAllowBeneficialInvestments(bool _allowBeneficialInvestments) external onlyOwner {
require(_allowBeneficialInvestments != allowBeneficialInvestments, "Value unchanged");
allowBeneficialInvestments = _allowBeneficialInvestments;
emit SetAllowBeneficialInvestments(allowBeneficialInvestments);
Expand Down Expand Up @@ -508,7 +508,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
uint256 _investmentValue,
FundRaiseType _fundRaiseType
)
public
external
view
returns(uint256 spentUSD, uint256 spentValue, uint256 tokensMinted)
{
Expand Down Expand Up @@ -732,7 +732,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* @param _amount Value to convert to USD
* @return uint256 Value in USD
*/
function convertToUSD(FundRaiseType _fundRaiseType, uint256 _amount) public view returns(uint256) {
function convertToUSD(FundRaiseType _fundRaiseType, uint256 _amount) external view returns(uint256) {
uint256 rate = getRate(_fundRaiseType);
return DecimalMath.mul(_amount, rate);
}
Expand All @@ -743,7 +743,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* @param _amount Value to convert from USD
* @return uint256 Value in ETH or POLY
*/
function convertFromUSD(FundRaiseType _fundRaiseType, uint256 _amount) public view returns(uint256) {
function convertFromUSD(FundRaiseType _fundRaiseType, uint256 _amount) external view returns(uint256) {
uint256 rate = getRate(_fundRaiseType);
return DecimalMath.div(_amount, rate);
}
Expand Down Expand Up @@ -776,7 +776,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* param _fundRaiseType The fund raising currency (e.g. ETH, POLY, SC) to calculate sold tokens for
* @return uint256 Total number of tokens sold for ETH
*/
function getTokensSoldFor(FundRaiseType _fundRaiseType) public view returns (uint256) {
function getTokensSoldFor(FundRaiseType _fundRaiseType) external view returns (uint256) {
uint256 tokensSold;
for (uint256 i = 0; i < tiers.length; i++) {
tokensSold = tokensSold.add(tiers[i].minted[uint8(_fundRaiseType)]);
Expand All @@ -789,7 +789,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* param _tier The tier to return minted tokens for
* @return uint256[] array of minted tokens in each fund raise type
*/
function getTokensMintedByTier(uint256 _tier) public view returns (uint256[]) {
function getTokensMintedByTier(uint256 _tier) external view returns (uint256[]) {
require(_tier < tiers.length, "Invalid tier");
uint256[] memory tokensMinted = new uint256[](3);
tokensMinted[0] = tiers[_tier].minted[uint8(FundRaiseType.ETH)];
Expand All @@ -803,7 +803,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* param _tier The tier to calculate sold tokens for
* @return uint256 Total number of tokens sold in the tier
*/
function getTokensSoldByTier(uint256 _tier) public view returns (uint256) {
function getTokensSoldByTier(uint256 _tier) external view returns (uint256) {
require(_tier < tiers.length, "Incorrect tier");
uint256 tokensSold;
tokensSold = tokensSold.add(tiers[_tier].minted[uint8(FundRaiseType.ETH)]);
Expand All @@ -816,15 +816,15 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* @notice Return the total no. of tiers
* @return uint256 Total number of tiers
*/
function getNumberOfTiers() public view returns (uint256) {
function getNumberOfTiers() external view returns (uint256) {
return tiers.length;
}

/**
* @notice Return the usd tokens accepted by the STO
* @return address[] usd tokens
*/
function getUsdTokens() public view returns (address[]) {
function getUsdTokens() external view returns (address[]) {
return usdTokens;
}

Expand All @@ -848,7 +848,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
* @return Amount of tokens sold.
* @return Array of bools to show if funding is allowed in ETH, POLY, SC respectively
*/
function getSTODetails() public view returns(uint256, uint256, uint256, uint256[], uint256[], uint256, uint256, uint256, bool[]) {
function getSTODetails() external view returns(uint256, uint256, uint256, uint256[], uint256[], uint256, uint256, uint256, bool[]) {
uint256[] memory cap = new uint256[](tiers.length);
uint256[] memory rate = new uint256[](tiers.length);
for(uint256 i = 0; i < tiers.length; i++) {
Expand Down
4 changes: 2 additions & 2 deletions contracts/proxy/USDTieredSTOProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import "../storage/USDTieredSTOStorage.sol";
import "./OwnedProxy.sol";
import "../Pausable.sol";
import "openzeppelin-solidity/contracts/ReentrancyGuard.sol";
import "../modules/STO/ISTOStorage.sol";
import "../modules/STO/STOStorage.sol";
import "../modules/ModuleStorage.sol";

/**
* @title USDTiered STO module Proxy
*/
contract USDTieredSTOProxy is USDTieredSTOStorage, ISTOStorage, ModuleStorage, Pausable, ReentrancyGuard, OwnedProxy {
contract USDTieredSTOProxy is USDTieredSTOStorage, STOStorage, ModuleStorage, Pausable, ReentrancyGuard, OwnedProxy {

/**
* @notice Constructor
Expand Down
3 changes: 0 additions & 3 deletions contracts/storage/USDTieredSTOStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ contract USDTieredSTOStorage {
// Whether or not the STO has been finalized
bool public isFinalized;

// Address where ETH, POLY & Stable Coin funds are delivered
address public wallet;

// Address of issuer reserve wallet for unsold tokens
address public reserveWallet;

Expand Down
Loading