Skip to content

usdtsto optimization #534

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

Merged
merged 4 commits into from
Jan 25, 2019
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
73 changes: 27 additions & 46 deletions contracts/modules/STO/USDTieredSTO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@ import "../../interfaces/IOracle.sol";
import "../../RegistryUpdater.sol";
import "../../libraries/DecimalMath.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/utils/ReentrancyGuard.sol";
import "../../storage/USDTieredSTOStorage.sol";

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

string public constant POLY_ORACLE = "PolyUsdOracle";
string public constant ETH_ORACLE = "EthUsdOracle";
string internal constant POLY_ORACLE = "PolyUsdOracle";
string internal constant ETH_ORACLE = "EthUsdOracle";

////////////
// Events //
Expand Down Expand Up @@ -200,10 +199,12 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
)
internal
{
require(_tokensPerTierTotal.length > 0, "No tiers provided");
require(
_ratePerTier.length == _tokensPerTierTotal.length && _ratePerTierDiscountPoly.length == _tokensPerTierTotal.length && _tokensPerTierDiscountPoly.length == _tokensPerTierTotal.length,
"Tier data length mismatch"
_tokensPerTierTotal.length > 0 &&
_ratePerTier.length == _tokensPerTierTotal.length &&
_ratePerTierDiscountPoly.length == _tokensPerTierTotal.length &&
_tokensPerTierDiscountPoly.length == _tokensPerTierTotal.length,
"Invalid Input"
);
delete tiers;
for (uint256 i = 0; i < _ratePerTier.length; i++) {
Expand Down Expand Up @@ -253,7 +254,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
* @notice Reserve address must be whitelisted to successfully finalize
*/
function finalize() public onlyOwner {
require(!isFinalized, "STO is already finalized");
require(!isFinalized, "STO already finalized");
isFinalized = true;
uint256 tempReturned;
uint256 tempSold;
Expand All @@ -266,7 +267,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
tiers[i].mintedTotal = tiers[i].tokenTotal;
}
}
require(ISecurityToken(securityToken).mint(reserveWallet, tempReturned), "Error in minting");
require(ISecurityToken(securityToken).mint(reserveWallet, tempReturned), "Minting Failed");
emit ReserveTokenMint(msg.sender, reserveWallet, tempReturned, currentTier);
finalAmountReturned = tempReturned;
totalTokensSold = tempSold;
Expand Down Expand Up @@ -437,7 +438,6 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
FundRaiseType _fundRaiseType
)
internal
nonReentrant
whenNotPaused
returns(uint256 spentUSD, uint256 spentValue)
{
Expand Down Expand Up @@ -485,10 +485,10 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
returns(uint256 netInvestedUSD)
{
require(isOpen(), "STO not open");
require(_investmentValue > 0, "No funds were sent");
require(_investmentValue > 0, "No funds sent");

// Check for minimum investment
require(investedUSD.add(investorInvestedUSD[_beneficiary]) >= minimumInvestmentUSD, "Total investment < minimumInvestmentUSD");
require(investedUSD.add(investorInvestedUSD[_beneficiary]) >= minimumInvestmentUSD, "Investment < min");
netInvestedUSD = investedUSD;
// Check for non-accredited cap
if (investors[_beneficiary].accredited == uint8(0)) {
Expand Down Expand Up @@ -565,7 +565,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
purchasedTokens = maximumTokens;
}
if (purchasedTokens > 0) {
require(ISecurityToken(securityToken).mint(_beneficiary, purchasedTokens), "Error in minting");
require(ISecurityToken(securityToken).mint(_beneficiary, purchasedTokens), "Mint failed");
emit TokenPurchase(msg.sender, _beneficiary, purchasedTokens, spentUSD, _tierPrice, _tier);
}
}
Expand All @@ -579,15 +579,8 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
* @return bool Whether the STO is accepting investments
*/
function isOpen() public view returns(bool) {
if (isFinalized)
return false;
/*solium-disable-next-line security/no-block-members*/
if (now < startTime)
return false;
/*solium-disable-next-line security/no-block-members*/
if (now >= endTime)
return false;
if (capReached())
/*solium-disable-next-line security/no-block-members*/
if (isFinalized || now < startTime || now >= endTime || capReached())
return false;
return true;
}
Expand All @@ -613,9 +606,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
} else if (_fundRaiseType == FundRaiseType.POLY) {
return IOracle(_getOracle(bytes32("POLY"), bytes32("USD"))).getPrice();
} else if (_fundRaiseType == FundRaiseType.SC) {
return 1 * 10**18;
} else {
revert("Incorrect funding");
return 10**18;
}
}

Expand All @@ -626,8 +617,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
* @return uint256 Value in USD
*/
function convertToUSD(FundRaiseType _fundRaiseType, uint256 _amount) public view returns(uint256) {
uint256 rate = getRate(_fundRaiseType);
return DecimalMath.mul(_amount, rate);
return DecimalMath.mul(_amount, getRate(_fundRaiseType));
}

/**
Expand All @@ -637,8 +627,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
* @return uint256 Value in ETH or POLY
*/
function convertFromUSD(FundRaiseType _fundRaiseType, uint256 _amount) public view returns(uint256) {
uint256 rate = getRate(_fundRaiseType);
return DecimalMath.div(_amount, rate);
return DecimalMath.div(_amount, getRate(_fundRaiseType));
}

/**
Expand All @@ -648,42 +637,36 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, ReentrancyGuard {
function getTokensSold() public view returns (uint256) {
if (isFinalized)
return totalTokensSold;
else
return getTokensMinted();
return getTokensMinted();
}

/**
* @notice Return the total no. of tokens minted
* @return uint256 Total number of tokens minted
*/
function getTokensMinted() public view returns (uint256) {
uint256 tokensMinted;
function getTokensMinted() public view returns (uint256 tokensMinted) {
for (uint256 i = 0; i < tiers.length; i++) {
tokensMinted = tokensMinted.add(tiers[i].mintedTotal);
}
return tokensMinted;
}

/**
* @notice Return the total no. of tokens sold for the given fund raise type
* 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) {
uint256 tokensSold;
function getTokensSoldFor(FundRaiseType _fundRaiseType) external view returns (uint256 tokensSold) {
for (uint256 i = 0; i < tiers.length; i++) {
tokensSold = tokensSold.add(tiers[i].minted[uint8(_fundRaiseType)]);
}
return tokensSold;
}

/**
* @notice Return array of minted tokens in each fund raise type for given tier
* 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[] memory) {
require(_tier < tiers.length, "Invalid tier");
function getTokensMintedByTier(uint256 _tier) external view returns(uint256[] memory) {
uint256[] memory tokensMinted = new uint256[](3);
tokensMinted[0] = tiers[_tier].minted[uint8(FundRaiseType.ETH)];
tokensMinted[1] = tiers[_tier].minted[uint8(FundRaiseType.POLY)];
Expand All @@ -696,8 +679,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, 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) {
require(_tier < tiers.length, "Incorrect tier");
function getTokensSoldByTier(uint256 _tier) external view returns (uint256) {
uint256 tokensSold;
tokensSold = tokensSold.add(tiers[_tier].minted[uint8(FundRaiseType.ETH)]);
tokensSold = tokensSold.add(tiers[_tier].minted[uint8(FundRaiseType.POLY)]);
Expand All @@ -709,23 +691,22 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, 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[] memory) {
function getUsdTokens() external view returns (address[] memory) {
return usdTokens;
}

/**
* @notice Return the permissions flag that are associated with STO
*/
function getPermissions() public view returns(bytes32[] memory) {
bytes32[] memory allPermissions = new bytes32[](0);
function getPermissions() public view returns(bytes32[] memory allPermissions) {
return allPermissions;
}

Expand All @@ -741,7 +722,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO, 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[] memory, uint256[] memory, uint256, uint256, uint256, bool[] memory) {
function getSTODetails() external view returns(uint256, uint256, uint256, uint256[] memory, uint256[] memory, uint256, uint256, uint256, bool[] memory) {
uint256[] memory cap = new uint256[](tiers.length);
uint256[] memory rate = new uint256[](tiers.length);
for(uint256 i = 0; i < tiers.length; i++) {
Expand Down
11 changes: 3 additions & 8 deletions contracts/storage/USDTieredSTOStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,17 @@ contract USDTieredSTOStorage {

mapping(bytes32 => mapping(bytes32 => string)) oracleKeys;

IERC20 public usdToken;

// Determine whether users can invest on behalf of a beneficiary
bool public allowBeneficialInvestments = false;
bool public allowBeneficialInvestments;

// Whether or not the STO has been finalized
bool public isFinalized;

// Address where ETH, POLY & DAI funds are delivered
address payable public wallet;

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

// List of stable coin addresses
address[] public usdTokens;
address[] internal usdTokens;

// Current tier
uint256 public currentTier;
Expand All @@ -74,7 +69,7 @@ contract USDTieredSTOStorage {
mapping (address => Investor) public investors;

// List of active stable coin addresses
mapping (address => bool) public usdTokenEnabled;
mapping (address => bool) internal usdTokenEnabled;

// List of all addresses that have been added as accredited or non-accredited without
// the default limit
Expand Down
8 changes: 4 additions & 4 deletions test/p_usd_tiered_sto.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ contract("USDTieredSTO", async (accounts) => {
_reserveWallet[stoId],
"Incorrect _reserveWallet in config"
);
assert.equal(await I_USDTieredSTO_Array[stoId].usdTokens.call(0), _usdToken[stoId][0], "Incorrect _usdToken in config");
assert.equal((await I_USDTieredSTO_Array[stoId].getUsdTokens())[0], _usdToken[stoId][0], "Incorrect _usdToken in config");
assert.equal(
await I_USDTieredSTO_Array[stoId].getNumberOfTiers(),
_tokensPerTierTotal[stoId].length,
Expand Down Expand Up @@ -567,7 +567,7 @@ contract("USDTieredSTO", async (accounts) => {
_reserveWallet[stoId],
"Incorrect _reserveWallet in config"
);
assert.equal(await I_USDTieredSTO_Array[stoId].usdTokens.call(0), _usdToken[stoId][0], "Incorrect _usdToken in config");
assert.equal((await I_USDTieredSTO_Array[stoId].getUsdTokens())[0], _usdToken[stoId][0], "Incorrect _usdToken in config");
assert.equal(
await I_USDTieredSTO_Array[stoId].getNumberOfTiers(),
_tokensPerTierTotal[stoId].length,
Expand Down Expand Up @@ -965,7 +965,7 @@ contract("USDTieredSTO", async (accounts) => {
"0x0000000000000000000003000000000000000000",
"STO Configuration doesn't set as expected"
);
assert.equal((await I_USDTieredSTO_Array[stoId].usdTokens.call(0)), accounts[3], "STO Configuration doesn't set as expected");
assert.equal((await I_USDTieredSTO_Array[stoId].getUsdTokens())[0], accounts[3], "STO Configuration doesn't set as expected");
});

it("Should fail to change config after endTime", async () => {
Expand Down Expand Up @@ -3868,7 +3868,7 @@ contract("USDTieredSTO", async (accounts) => {
let init_WalletETHBal = new BN(await web3.eth.getBalance(WALLET));
let init_WalletPOLYBal = await I_PolyToken.balanceOf(WALLET);

let tokensToMint = (await I_USDTieredSTO_Array[stoId].buyWithPOLY.call(ACCREDITED1, investment_POLY))[2];
let tokensToMint = (await I_USDTieredSTO_Array[stoId].buyWithPOLY.call(ACCREDITED1, investment_POLY, {from: ACCREDITED1}))[2];

// Buy With POLY
let tx2 = await I_USDTieredSTO_Array[stoId].buyWithPOLY(ACCREDITED1, investment_POLY, {
Expand Down