Skip to content

Commit 37e968f

Browse files
authored
Merge branch 'dev-2.1.0' into sto-finalize-fix
2 parents 6f9c378 + fd51e7a commit 37e968f

File tree

10 files changed

+57
-71
lines changed

10 files changed

+57
-71
lines changed

contracts/interfaces/ISTO.sol

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
pragma solidity ^0.4.24;
2+
3+
/**
4+
* @title Interface to be implemented by all STO modules
5+
*/
6+
interface ISTO {
7+
/**
8+
* @notice Returns the total no. of tokens sold
9+
*/
10+
function getTokensSold() external view returns (uint256);
11+
}

contracts/modules/STO/CappedSTO.sol

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
pragma solidity ^0.4.24;
22

3-
import "./ISTO.sol";
3+
import "./STO.sol";
44
import "../../interfaces/ISecurityToken.sol";
55
import "openzeppelin-solidity/contracts/ReentrancyGuard.sol";
66
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
77

88
/**
99
* @title STO module for standard capped crowdsale
1010
*/
11-
contract CappedSTO is ISTO, ReentrancyGuard {
11+
contract CappedSTO is STO, ReentrancyGuard {
1212
using SafeMath for uint256;
1313

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

117117
_forwardFunds(refund);
118-
_postValidatePurchase(_beneficiary, weiAmount);
119118
}
120119

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

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

204202
_processPurchase(_beneficiary, tokens);
205203
emit TokenPurchase(msg.sender, _beneficiary, _investedAmount, tokens);
206-
207-
_updatePurchasingState(_beneficiary, _investedAmount);
208204
}
209205

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

226-
/**
227-
* @notice Validation of an executed purchase.
228-
Observe state and use revert statements to undo rollback when valid conditions are not met.
229-
*/
230-
function _postValidatePurchase(address /*_beneficiary*/, uint256 /*_investedAmount*/) internal pure {
231-
// optional override
232-
}
233-
234219
/**
235220
* @notice Source of tokens.
236221
Override this method to modify the way in which the crowdsale ultimately gets and sends its tokens.
@@ -255,27 +240,23 @@ contract CappedSTO is ISTO, ReentrancyGuard {
255240
_deliverTokens(_beneficiary, _tokenAmount);
256241
}
257242

258-
/**
259-
* @notice Overrides for extensions that require an internal state to check for validity
260-
(current user contributions, etc.)
261-
*/
262-
function _updatePurchasingState(address /*_beneficiary*/, uint256 /*_investedAmount*/) internal pure {
263-
// optional override
264-
}
265-
266243
/**
267244
* @notice Overrides to extend the way in which ether is converted to tokens.
268245
* @param _investedAmount Value in wei to be converted into tokens
269246
* @return Number of tokens that can be purchased with the specified _investedAmount
270247
* @return Remaining amount that should be refunded to the investor
271248
*/
272-
function _getTokenAmount(uint256 _investedAmount) internal view returns (uint256 _tokens, uint256 _refund) {
273-
_tokens = _investedAmount.mul(rate);
274-
_tokens = _tokens.div(uint256(10) ** 18);
249+
function _getTokenAmount(uint256 _investedAmount) internal view returns (uint256 tokens, uint256 refund) {
250+
tokens = _investedAmount.mul(rate);
251+
tokens = tokens.div(uint256(10) ** 18);
252+
if (totalTokensSold.add(tokens) > cap) {
253+
tokens = cap.sub(totalTokensSold);
254+
}
275255
uint256 granularity = ISecurityToken(securityToken).granularity();
276-
_tokens = _tokens.div(granularity);
277-
_tokens = _tokens.mul(granularity);
278-
_refund = _investedAmount.sub((_tokens.mul(uint256(10) ** 18)).div(rate));
256+
tokens = tokens.div(granularity);
257+
tokens = tokens.mul(granularity);
258+
require(tokens > 0, "Cap reached");
259+
refund = _investedAmount.sub((tokens.mul(uint256(10) ** 18)).div(rate));
279260
}
280261

281262
/**

contracts/modules/STO/DummySTO.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
pragma solidity ^0.4.24;
22

3-
import "./ISTO.sol";
3+
import "./STO.sol";
44
import "../../interfaces/ISecurityToken.sol";
55

66
/**
77
* @title STO module for sample implementation of a different crowdsale module
88
*/
9-
contract DummySTO is ISTO {
9+
contract DummySTO is STO {
1010

1111
bytes32 public constant ADMIN = "ADMIN";
1212

contracts/modules/STO/PreSaleSTO.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
pragma solidity ^0.4.24;
22

3-
import "./ISTO.sol";
3+
import "./STO.sol";
44
import "../../interfaces/ISecurityToken.sol";
55
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
66

77
/**
88
* @title STO module for private presales
99
*/
10-
contract PreSaleSTO is ISTO {
10+
contract PreSaleSTO is STO {
1111
using SafeMath for uint256;
1212

1313
bytes32 public constant PRE_SALE_ADMIN = "PRE_SALE_ADMIN";

contracts/modules/STO/ISTO.sol renamed to contracts/modules/STO/STO.sol

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@ pragma solidity ^0.4.24;
33
import "../../Pausable.sol";
44
import "../Module.sol";
55
import "../../interfaces/IERC20.sol";
6-
import "./ISTOStorage.sol";
6+
import "../../interfaces/ISTO.sol";
7+
import "./STOStorage.sol";
78
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
89

910
/**
1011
* @title Interface to be implemented by all STO modules
1112
*/
12-
contract ISTO is ISTOStorage, Module, Pausable {
13+
contract STO is ISTO, STOStorage, Module, Pausable {
1314
using SafeMath for uint256;
1415

1516
enum FundRaiseType { ETH, POLY, SC }
16-
17+
1718
// Event
1819
event SetFundRaiseTypes(FundRaiseType[] _fundRaiseTypes);
1920

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

39-
/**
40-
* @notice Returns the total no. of tokens sold
41-
*/
42-
function getTokensSold() public view returns (uint256);
43-
4440
/**
4541
* @notice Pause (overridden function)
4642
*/
@@ -59,7 +55,7 @@ contract ISTO is ISTOStorage, Module, Pausable {
5955

6056
function _setFundRaiseType(FundRaiseType[] _fundRaiseTypes) internal {
6157
// FundRaiseType[] parameter type ensures only valid values for _fundRaiseTypes
62-
require(_fundRaiseTypes.length > 0, "Raise type is not specified");
58+
require(_fundRaiseTypes.length > 0 && _fundRaiseTypes.length <= 3, "Raise type is not specified");
6359
fundRaiseTypes[uint8(FundRaiseType.ETH)] = false;
6460
fundRaiseTypes[uint8(FundRaiseType.POLY)] = false;
6561
fundRaiseTypes[uint8(FundRaiseType.SC)] = false;

contracts/modules/STO/ISTOStorage.sol renamed to contracts/modules/STO/STOStorage.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
pragma solidity ^0.4.24;
22

33
/**
4-
* @title Storage layout for the ISTO contract
4+
* @title Storage layout for the STO contract
55
*/
6-
contract ISTOStorage {
6+
contract STOStorage {
77

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

24-
}
24+
}

contracts/modules/STO/USDTieredSTO.sol

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pragma solidity ^0.4.24;
22

3-
import "./ISTO.sol";
3+
import "./STO.sol";
44
import "../../interfaces/ISecurityToken.sol";
55
import "../../interfaces/IOracle.sol";
66
import "../../RegistryUpdater.sol";
@@ -12,7 +12,7 @@ import "../../storage/USDTieredSTOStorage.sol";
1212
/**
1313
* @title STO module for standard capped crowdsale
1414
*/
15-
contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
15+
contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
1616
using SafeMath for uint256;
1717

1818
string public constant POLY_ORACLE = "PolyUsdOracle";
@@ -262,7 +262,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
262262
}
263263
usdTokens = _usdTokens;
264264
for(i = 0; i < _usdTokens.length; i++) {
265-
require(_usdTokens[i] != address(0), "Invalid USD token");
265+
require(_usdTokens[i] != address(0) && _usdTokens[i] != address(polyToken), "Invalid USD token");
266266
usdTokenEnabled[_usdTokens[i]] = true;
267267
}
268268
emit SetAddresses(wallet, reserveWallet, _usdTokens);
@@ -276,7 +276,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
276276
* @notice Finalizes the STO and mint remaining tokens to reserve address
277277
* @notice Reserve address must be whitelisted to successfully finalize
278278
*/
279-
function finalize() public onlyOwner {
279+
function finalize() external onlyOwner {
280280
require(!isFinalized, "STO is already finalized");
281281
isFinalized = true;
282282
uint256 tempReturned;
@@ -304,7 +304,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
304304
* @param _investors Array of investor addresses to modify
305305
* @param _accredited Array of bools specifying accreditation status
306306
*/
307-
function changeAccredited(address[] _investors, bool[] _accredited) public onlyOwner {
307+
function changeAccredited(address[] _investors, bool[] _accredited) external onlyOwner {
308308
require(_investors.length == _accredited.length, "Array length mismatch");
309309
for (uint256 i = 0; i < _investors.length; i++) {
310310
if (_accredited[i]) {
@@ -322,7 +322,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
322322
* @param _investors Array of investor addresses to modify
323323
* @param _nonAccreditedLimit Array of uints specifying non-accredited limits
324324
*/
325-
function changeNonAccreditedLimit(address[] _investors, uint256[] _nonAccreditedLimit) public onlyOwner {
325+
function changeNonAccreditedLimit(address[] _investors, uint256[] _nonAccreditedLimit) external onlyOwner {
326326
//nonAccreditedLimitUSDOverride
327327
require(_investors.length == _nonAccreditedLimit.length, "Array length mismatch");
328328
for (uint256 i = 0; i < _investors.length; i++) {
@@ -360,7 +360,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
360360
* @notice Function to set allowBeneficialInvestments (allow beneficiary to be different to funder)
361361
* @param _allowBeneficialInvestments Boolean to allow or disallow beneficial investments
362362
*/
363-
function changeAllowBeneficialInvestments(bool _allowBeneficialInvestments) public onlyOwner {
363+
function changeAllowBeneficialInvestments(bool _allowBeneficialInvestments) external onlyOwner {
364364
require(_allowBeneficialInvestments != allowBeneficialInvestments, "Value unchanged");
365365
allowBeneficialInvestments = _allowBeneficialInvestments;
366366
emit SetAllowBeneficialInvestments(allowBeneficialInvestments);
@@ -511,7 +511,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
511511
uint256 _investmentValue,
512512
FundRaiseType _fundRaiseType
513513
)
514-
public
514+
external
515515
view
516516
returns(uint256 spentUSD, uint256 spentValue, uint256 tokensMinted)
517517
{
@@ -735,7 +735,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
735735
* @param _amount Value to convert to USD
736736
* @return uint256 Value in USD
737737
*/
738-
function convertToUSD(FundRaiseType _fundRaiseType, uint256 _amount) public view returns(uint256) {
738+
function convertToUSD(FundRaiseType _fundRaiseType, uint256 _amount) external view returns(uint256) {
739739
uint256 rate = getRate(_fundRaiseType);
740740
return DecimalMath.mul(_amount, rate);
741741
}
@@ -746,7 +746,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
746746
* @param _amount Value to convert from USD
747747
* @return uint256 Value in ETH or POLY
748748
*/
749-
function convertFromUSD(FundRaiseType _fundRaiseType, uint256 _amount) public view returns(uint256) {
749+
function convertFromUSD(FundRaiseType _fundRaiseType, uint256 _amount) external view returns(uint256) {
750750
uint256 rate = getRate(_fundRaiseType);
751751
return DecimalMath.div(_amount, rate);
752752
}
@@ -779,7 +779,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
779779
* param _fundRaiseType The fund raising currency (e.g. ETH, POLY, SC) to calculate sold tokens for
780780
* @return uint256 Total number of tokens sold for ETH
781781
*/
782-
function getTokensSoldFor(FundRaiseType _fundRaiseType) public view returns (uint256) {
782+
function getTokensSoldFor(FundRaiseType _fundRaiseType) external view returns (uint256) {
783783
uint256 tokensSold;
784784
for (uint256 i = 0; i < tiers.length; i++) {
785785
tokensSold = tokensSold.add(tiers[i].minted[uint8(_fundRaiseType)]);
@@ -792,7 +792,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
792792
* param _tier The tier to return minted tokens for
793793
* @return uint256[] array of minted tokens in each fund raise type
794794
*/
795-
function getTokensMintedByTier(uint256 _tier) public view returns (uint256[]) {
795+
function getTokensMintedByTier(uint256 _tier) external view returns (uint256[]) {
796796
require(_tier < tiers.length, "Invalid tier");
797797
uint256[] memory tokensMinted = new uint256[](3);
798798
tokensMinted[0] = tiers[_tier].minted[uint8(FundRaiseType.ETH)];
@@ -806,7 +806,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
806806
* param _tier The tier to calculate sold tokens for
807807
* @return uint256 Total number of tokens sold in the tier
808808
*/
809-
function getTokensSoldByTier(uint256 _tier) public view returns (uint256) {
809+
function getTokensSoldByTier(uint256 _tier) external view returns (uint256) {
810810
require(_tier < tiers.length, "Incorrect tier");
811811
uint256 tokensSold;
812812
tokensSold = tokensSold.add(tiers[_tier].minted[uint8(FundRaiseType.ETH)]);
@@ -819,15 +819,15 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
819819
* @notice Return the total no. of tiers
820820
* @return uint256 Total number of tiers
821821
*/
822-
function getNumberOfTiers() public view returns (uint256) {
822+
function getNumberOfTiers() external view returns (uint256) {
823823
return tiers.length;
824824
}
825825

826826
/**
827827
* @notice Return the usd tokens accepted by the STO
828828
* @return address[] usd tokens
829829
*/
830-
function getUsdTokens() public view returns (address[]) {
830+
function getUsdTokens() external view returns (address[]) {
831831
return usdTokens;
832832
}
833833

@@ -851,7 +851,7 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard {
851851
* @return Amount of tokens sold.
852852
* @return Array of bools to show if funding is allowed in ETH, POLY, SC respectively
853853
*/
854-
function getSTODetails() public view returns(uint256, uint256, uint256, uint256[], uint256[], uint256, uint256, uint256, bool[]) {
854+
function getSTODetails() external view returns(uint256, uint256, uint256, uint256[], uint256[], uint256, uint256, uint256, bool[]) {
855855
uint256[] memory cap = new uint256[](tiers.length);
856856
uint256[] memory rate = new uint256[](tiers.length);
857857
for(uint256 i = 0; i < tiers.length; i++) {

contracts/proxy/USDTieredSTOProxy.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import "../storage/USDTieredSTOStorage.sol";
44
import "./OwnedProxy.sol";
55
import "../Pausable.sol";
66
import "openzeppelin-solidity/contracts/ReentrancyGuard.sol";
7-
import "../modules/STO/ISTOStorage.sol";
7+
import "../modules/STO/STOStorage.sol";
88
import "../modules/ModuleStorage.sol";
99

1010
/**
1111
* @title USDTiered STO module Proxy
1212
*/
13-
contract USDTieredSTOProxy is USDTieredSTOStorage, ISTOStorage, ModuleStorage, Pausable, ReentrancyGuard, OwnedProxy {
13+
contract USDTieredSTOProxy is USDTieredSTOStorage, STOStorage, ModuleStorage, Pausable, ReentrancyGuard, OwnedProxy {
1414

1515
/**
1616
* @notice Constructor

contracts/storage/USDTieredSTOStorage.sol

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ contract USDTieredSTOStorage {
5151
// Whether or not the STO has been finalized
5252
bool public isFinalized;
5353

54-
// Address where ETH, POLY & Stable Coin funds are delivered
55-
address public wallet;
56-
5754
// Address of issuer reserve wallet for unsold tokens
5855
address public reserveWallet;
5956

0 commit comments

Comments
 (0)