diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e1bbb0c4..4cd726971 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ All notable changes to this project will be documented in this file. * Removed individual mappings for tier data removed in UDSTSTO. * Removed the old Proxy deployment method of USDTieredSTO and adopt the new inherited proxy deployment approach. * Bump the version to `2.1.0` +* Added `getAccreditedData` to return accredited & non-accredited investor data ## GeneralTransferManager * `getInvestors`, `getAllInvestorsData`, `getInvestorsData` added to GTM to allow easy data queries. @@ -31,7 +32,7 @@ All notable changes to this project will be documented in this file. * Changed the version of `GeneralTransferManagerFactory` from `1.0.0` to `2.1.0`. ## Manual Approval TransferManager -* Removed `0x0` check for the `_from` address to `ManualApprovalTransferManager`. This allows for the Issuer/Transfer Agent to approve a one-off mint of tokens that otherwise would not be possible. +* Removed `0x0` check for the `_from` address to `ManualApprovalTransferManager`. This allows for the Issuer/Transfer Agent to approve a one-off mint of tokens that otherwise would not be possible. * Changed the version of `ManualApprovalTransferManagerFactory` from `1.0.0` to `2.1.0`. * Deployed 2.0.1 `ManualApprovalTransferManagerFactory` to address 0x6af2afad53cb334e62b90ddbdcf3a086f654c298 * Add `getActiveApprovalsToUser()` function to access all the active approvals for a user whether user is in the `from` or in `to`. @@ -97,7 +98,7 @@ volume traded in a given rolling period. * Removed investors list pruning * Remove `swarmHash` from the `registerTicker(), addCustomTicker(), generateSecurityToken(), addCustomSecurityToken()` functions of TickerRegistry.sol and SecurityTokenRegistry.sol. #230 * Remove `Log` prefix from all the event present in the ecosystem. -* Removed `addTagByModuleType` & `removeTagsByModuleType` from MR. +* Removed `addTagByModuleType` & `removeTagsByModuleType` from MR. ====== diff --git a/CLI/commands/investor_portal.js b/CLI/commands/investor_portal.js index 613414a71..0cb02f681 100644 --- a/CLI/commands/investor_portal.js +++ b/CLI/commands/investor_portal.js @@ -245,7 +245,7 @@ async function processAddressWithBalance(array) { for (const address of array) { let symbol = await checkSymbol(address); let balance = await checkBalance(address); - list.push({'address': address, 'symbol': symbol, 'balance': balance}) + list.push({ 'address': address, 'symbol': symbol, 'balance': balance }) } return list } @@ -254,7 +254,7 @@ async function processAddress(array) { let list = []; for (const address of array) { let symbol = await checkSymbol(address); - list.push({"symbol": symbol, "address": address}) + list.push({ "symbol": symbol, "address": address }) } return list } @@ -277,8 +277,7 @@ async function checkBalance(address) { } } -async function showUserInfoForUSDTieredSTO() -{ +async function showUserInfoForUSDTieredSTO() { let stableSymbols = []; let listOfStableCoins = await currentSTO.methods.getUsdTokens().call(); @@ -306,11 +305,12 @@ async function showUserInfoForUSDTieredSTO() console.log(` - Whitelisted: ${(displayCanBuy) ? 'YES' : 'NO'}`); console.log(` - Valid KYC: ${(displayValidKYC) ? 'YES' : 'NO'}`); - let displayIsUserAccredited = await currentSTO.methods.accredited(User.address).call(); + let investorData = await currentSTO.methods.investors(User.address).call(); + let displayIsUserAccredited = investorData.accredited == 1; console.log(` - Accredited: ${(displayIsUserAccredited) ? "YES" : "NO"}`) - if (!await currentSTO.methods.accredited(User.address).call()) { - let displayOverrideNonAccreditedLimitUSD = web3.utils.fromWei(await currentSTO.methods.nonAccreditedLimitUSDOverride(User.address).call()) + if (!displayIsUserAccredited) { + let displayOverrideNonAccreditedLimitUSD = web3.utils.fromWei(investorData.nonAccreditedLimitUSDOverride); let displayNonAccreditedLimitUSD = displayOverrideNonAccreditedLimitUSD != 0 ? displayOverrideNonAccreditedLimitUSD : web3.utils.fromWei(await currentSTO.methods.nonAccreditedLimitUSD().call()); let displayTokensRemainingAllocation = displayNonAccreditedLimitUSD - displayInvestorInvestedUSD; console.log(` - Remaining allocation: ${(displayTokensRemainingAllocation > 0 ? displayTokensRemainingAllocation : 0)} USD`); @@ -402,7 +402,7 @@ async function showUSDTieredSTOInfo() { }) } else { displayFundsRaisedPerType += ` - ${type}:\t\t\t ${fundsRaised} ${type}`; + ${type}:\t\t\t ${fundsRaised} ${type}`; } //Only show sold per raise type is more than one are allowed if (raiseTypes.length > 1) { @@ -420,7 +420,7 @@ async function showUSDTieredSTOInfo() { let displayRaiseType = raiseTypes.join(' - '); //If STO has stable coins, we list them one by one if (stableSymbols.length) { - displayRaiseType = displayRaiseType.replace(STABLE, "") + `${stableSymbols.map((obj) => {return obj.symbol}).toString().replace(`,`,` - `)}` + displayRaiseType = displayRaiseType.replace(STABLE, "") + `${stableSymbols.map((obj) => { return obj.symbol }).toString().replace(`,`, ` - `)}` } let now = Math.floor(Date.now() / 1000); diff --git a/CLI/commands/sto_manager.js b/CLI/commands/sto_manager.js index be809312e..f581b7339 100644 --- a/CLI/commands/sto_manager.js +++ b/CLI/commands/sto_manager.js @@ -5,6 +5,7 @@ const abis = require('./helpers/contract_abis'); const common = require('./common/common_functions'); const gbl = require('./common/global'); const csvParse = require('./helpers/csv'); +const { table } = require('table'); const STABLE = 'STABLE'; /////////////////// @@ -45,8 +46,8 @@ async function executeApp() { } options.push('Add new STO module'); - let index = readlineSync.keyInSelect(options, 'What do you want to do?', { cancel: 'Exit' }); - let optionSelected = index != -1 ? options[index] : 'Exit'; + let index = readlineSync.keyInSelect(options, 'What do you want to do?', { cancel: 'EXIT' }); + let optionSelected = index != -1 ? options[index] : 'EXIT'; console.log('Selected:', optionSelected, '\n'); switch (optionSelected) { case 'Show existing STO information': @@ -60,7 +61,7 @@ async function executeApp() { case 'Add new STO module': await addSTOModule(); break; - case 'Exit': + case 'EXIT': exit = true; break; } @@ -97,6 +98,7 @@ async function showSTO(selectedSTO, currentSTO) { break; case 'USDTieredSTO': await usdTieredSTO_status(currentSTO); + await showAccreditedData(currentSTO); break; } } @@ -126,8 +128,8 @@ async function addSTOModule(stoConfig) { let moduleFactory = new web3.eth.Contract(moduleFactoryABI, m); return web3.utils.hexToUtf8(await moduleFactory.methods.name().call()); })); - let index = readlineSync.keyInSelect(options, 'What type of STO do you want?', { cancel: 'Return' }); - optionSelected = index != -1 ? options[index] : 'Return'; + let index = readlineSync.keyInSelect(options, 'What type of STO do you want?', { cancel: 'RETURN' }); + optionSelected = index != -1 ? options[index] : 'RETURN'; } else { optionSelected = stoConfig.type; } @@ -271,8 +273,6 @@ async function cappedSTO_status(currentSTO) { - Tokens remaining: ${web3.utils.fromWei(displayCap.sub(displayTokensSold))} ${displayTokenSymbol.toUpperCase()} - Investor count: ${displayInvestorCount} `); - - console.log(chalk.green(`\n${(web3.utils.fromWei(await getBalance(Issuer.address, gbl.constants.FUND_RAISE_TYPES.POLY)))} POLY balance remaining at issuer address ${Issuer.address}`)); } //////////////////// @@ -579,6 +579,7 @@ async function usdTieredSTO_status(currentSTO) { let displayStartTime = await currentSTO.methods.startTime().call(); let displayEndTime = await currentSTO.methods.endTime().call(); let displayCurrentTier = parseInt(await currentSTO.methods.currentTier().call()) + 1; + let test = await currentSTO.methods.nonAccreditedLimitUSD().call(); let displayNonAccreditedLimitUSD = web3.utils.fromWei(await currentSTO.methods.nonAccreditedLimitUSD().call()); let displayMinimumInvestmentUSD = web3.utils.fromWei(await currentSTO.methods.minimumInvestmentUSD().call()); let displayWallet = await currentSTO.methods.wallet().call(); @@ -752,8 +753,6 @@ async function usdTieredSTO_status(currentSTO) { + displayFundsRaisedPerType + ` Total USD: ${displayFundsRaisedUSD} USD `); - - console.log(chalk.green(`\n${(web3.utils.fromWei(await getBalance(Issuer.address, gbl.constants.FUND_RAISE_TYPES.POLY)))} POLY balance remaining at issuer address ${Issuer.address}`)); } async function checkStableBalance(walletAddress, stableAddress) { @@ -789,9 +788,10 @@ async function usdTieredSTO_configure(currentSTO) { 'Modify limits configuration', 'Modify funding configuration'); } - let index = readlineSync.keyInSelect(options, 'What do you want to do?'); - switch (index) { - case 0: + let index = readlineSync.keyInSelect(options, 'What do you want to do?', { cancel: 'RETURN' }); + let selected = index != -1 ? options[index] : 'Exit'; + switch (selected) { + case 'Finalize STO': let reserveWallet = await currentSTO.methods.reserveWallet().call(); let isVerified = await securityToken.methods.verifyTransfer('0x0000000000000000000000000000000000000000', reserveWallet, 0, web3.utils.fromAscii("")).call(); if (isVerified) { @@ -803,7 +803,7 @@ async function usdTieredSTO_configure(currentSTO) { console.log(chalk.red(`Reserve wallet (${reserveWallet}) is not able to receive remaining tokens. Check if this address is whitelisted.`)); } break; - case 1: + case 'Change accredited account': let investor = readlineSync.question('Enter the address to change accreditation: '); let isAccredited = readlineSync.keyInYNStrict(`Is ${investor} accredited?`); let investors = [investor]; @@ -812,10 +812,10 @@ async function usdTieredSTO_configure(currentSTO) { // 2 GAS? await common.sendTransaction(changeAccreditedAction); break; - case 2: + case 'Change accredited in batch': await changeAccreditedInBatch(currentSTO); break; - case 3: + case 'Change non accredited limit for an account': let account = readlineSync.question('Enter the address to change non accredited limit: '); let limit = readlineSync.question(`Enter the limit in USD: `); let accounts = [account]; @@ -823,26 +823,26 @@ async function usdTieredSTO_configure(currentSTO) { let changeNonAccreditedLimitAction = currentSTO.methods.changeNonAccreditedLimit(accounts, limits); await common.sendTransaction(changeNonAccreditedLimitAction); break; - case 4: + case 'Change non accredited limits in batch': await changeNonAccreditedLimitsInBatch(currentSTO); break; - case 5: + case 'Modify times configuration': await modfifyTimes(currentSTO); await usdTieredSTO_status(currentSTO); break; - case 6: + case 'Modify tiers configuration': await modfifyTiers(currentSTO); await usdTieredSTO_status(currentSTO); break; - case 7: + case 'Modify addresses configuration': await modfifyAddresses(currentSTO); await usdTieredSTO_status(currentSTO); break; - case 8: + case 'Modify limits configuration': await modfifyLimits(currentSTO); await usdTieredSTO_status(currentSTO); break; - case 9: + case 'Modify funding configuration': await modfifyFunding(currentSTO); await usdTieredSTO_status(currentSTO); break; @@ -850,6 +850,33 @@ async function usdTieredSTO_configure(currentSTO) { } } +async function showAccreditedData(currentSTO) { + let accreditedData = await currentSTO.methods.getAccreditedData().call(); + let investorArray = accreditedData[0]; + let accreditedArray = accreditedData[1]; + let nonAccreditedLimitArray = accreditedData[2]; + + if (investorArray.length > 0) { + let dataTable = [['Investor', 'Is accredited', 'Non-accredited limit (USD)']]; + for (let i = 0; i < investorArray.length; i++) { + dataTable.push([ + investorArray[i], + accreditedArray[i] ? 'YES' : 'NO', + accreditedArray[i] ? 'N/A' : (nonAccreditedLimitArray[i] !== '0' ? web3.utils.fromWei(nonAccreditedLimitArray[i]) : 'default') + ]); + } + console.log(); + console.log(`************************************ ACCREDITED DATA *************************************`); + console.log(); + console.log(table(dataTable)); + } else { + console.log(); + console.log(chalk.yellow(`There is no accredited data to show`)); + console.log(); + } + +} + async function changeAccreditedInBatch(currentSTO) { let csvFilePath = readlineSync.question(`Enter the path for csv data file (${ACCREDIT_DATA_CSV}): `, { defaultInput: ACCREDIT_DATA_CSV @@ -898,6 +925,7 @@ async function changeNonAccreditedLimitsInBatch(currentSTO) { let batches = common.splitIntoBatches(validData, batchSize); let [investorArray, limitArray] = common.transposeBatches(batches); for (let batch = 0; batch < batches.length; batch++) { + limitArray[batch] = limitArray[batch].map(a => web3.utils.toWei(new web3.utils.BN(a))); console.log(`Batch ${batch + 1} - Attempting to change non accredited limit to accounts:\n\n`, investorArray[batch], '\n'); let action = currentSTO.methods.changeNonAccreditedLimit(investorArray[batch], limitArray[batch]); let receipt = await common.sendTransaction(action); @@ -1052,8 +1080,8 @@ async function selectToken() { }); options.push('Enter token symbol manually'); - let index = readlineSync.keyInSelect(options, 'Select a token:', { cancel: 'Exit' }); - let selected = index != -1 ? options[index] : 'Exit'; + let index = readlineSync.keyInSelect(options, 'Select a token:', { cancel: 'EXIT' }); + let selected = index != -1 ? options[index] : 'EXIT'; switch (selected) { case 'Enter token symbol manually': result = readlineSync.question('Enter the token symbol: '); diff --git a/contracts/modules/STO/USDTieredSTO.sol b/contracts/modules/STO/USDTieredSTO.sol index 47e659299..b3a248da5 100644 --- a/contracts/modules/STO/USDTieredSTO.sol +++ b/contracts/modules/STO/USDTieredSTO.sol @@ -306,7 +306,12 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { function changeAccredited(address[] _investors, bool[] _accredited) public onlyOwner { require(_investors.length == _accredited.length, "Array length mismatch"); for (uint256 i = 0; i < _investors.length; i++) { - accredited[_investors[i]] = _accredited[i]; + if (_accredited[i]) { + investors[_investors[i]].accredited = uint8(1); + } else { + investors[_investors[i]].accredited = uint8(0); + } + _addToInvestorsList(_investors[i]); emit SetAccredited(_investors[i], _accredited[i]); } } @@ -320,12 +325,36 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { //nonAccreditedLimitUSDOverride require(_investors.length == _nonAccreditedLimit.length, "Array length mismatch"); for (uint256 i = 0; i < _investors.length; i++) { - require(_nonAccreditedLimit[i] > 0, "Limit = 0"); - nonAccreditedLimitUSDOverride[_investors[i]] = _nonAccreditedLimit[i]; + investors[_investors[i]].nonAccreditedLimitUSDOverride = _nonAccreditedLimit[i]; + _addToInvestorsList(_investors[i]); emit SetNonAccreditedLimit(_investors[i], _nonAccreditedLimit[i]); } } + function _addToInvestorsList(address _investor) internal { + if (investors[_investor].seen == uint8(0)) { + investors[_investor].seen = uint8(1); + investorsList.push(_investor); + } + } + + /** + * @notice Returns investor accredited & non-accredited override informatiomn + * @return address[] list of all configured investors + * @return bool[] whether investor is accredited + * @return uint256[] any USD overrides for non-accredited limits for the investor + */ + function getAccreditedData() external view returns (address[], bool[], uint256[]) { + bool[] memory accrediteds = new bool[](investorsList.length); + uint256[] memory nonAccreditedLimitUSDOverrides = new uint256[](investorsList.length); + uint256 i; + for (i = 0; i < investorsList.length; i++) { + accrediteds[i] = (investors[investorsList[i]].accredited == uint8(0)? false: true); + nonAccreditedLimitUSDOverrides[i] = investors[investorsList[i]].nonAccreditedLimitUSDOverride; + } + return (investorsList, accrediteds, nonAccreditedLimitUSDOverrides); + } + /** * @notice Function to set allowBeneficialInvestments (allow beneficiary to be different to funder) * @param _allowBeneficialInvestments Boolean to allow or disallow beneficial investments @@ -525,8 +554,8 @@ contract USDTieredSTO is USDTieredSTOStorage, ISTO, ReentrancyGuard { require(investedUSD.add(investorInvestedUSD[_beneficiary]) >= minimumInvestmentUSD, "Total investment < minimumInvestmentUSD"); netInvestedUSD = investedUSD; // Check for non-accredited cap - if (!accredited[_beneficiary]) { - uint256 investorLimitUSD = (nonAccreditedLimitUSDOverride[_beneficiary] == 0) ? nonAccreditedLimitUSD : nonAccreditedLimitUSDOverride[_beneficiary]; + if (investors[_beneficiary].accredited == uint8(0)) { + uint256 investorLimitUSD = (investors[_beneficiary].nonAccreditedLimitUSDOverride == 0) ? nonAccreditedLimitUSD : investors[_beneficiary].nonAccreditedLimitUSDOverride; require(investorInvestedUSD[_beneficiary] < investorLimitUSD, "Over Non-accredited investor limit"); if (investedUSD.add(investorInvestedUSD[_beneficiary]) > investorLimitUSD) netInvestedUSD = investorLimitUSD.sub(investorInvestedUSD[_beneficiary]); diff --git a/contracts/modules/STO/USDTieredSTOStorage.sol b/contracts/modules/STO/USDTieredSTOStorage.sol index 5d9581408..c9df0f24c 100644 --- a/contracts/modules/STO/USDTieredSTOStorage.sol +++ b/contracts/modules/STO/USDTieredSTOStorage.sol @@ -34,6 +34,15 @@ contract USDTieredSTOStorage { uint256 mintedDiscountPoly; } + struct Investor { + // Whether investor is accredited (0 = non-accredited, 1 = accredited) + uint8 accredited; + // Whether we have seen the investor before (already added to investors list) + uint8 seen; + // Overrides for default limit in USD for non-accredited investors multiplied by 10**18 (0 = no override) + uint256 nonAccreditedLimitUSDOverride; + } + mapping (bytes32 => mapping (bytes32 => string)) oracleKeys; // Determine whether users can invest on behalf of a beneficiary @@ -66,18 +75,19 @@ contract USDTieredSTOStorage { // Amount in fund raise type invested by each investor mapping (address => mapping (uint8 => uint256)) public investorInvested; - // List of accredited investors - mapping (address => bool) public accredited; + // Accredited & non-accredited investor data + mapping (address => Investor) public investors; // List of active stable coin addresses mapping (address => bool) public usdTokenEnabled; + // List of all addresses that have been added as accredited or non-accredited without + // the default limit + address[] public investorsList; + // Default limit in USD for non-accredited investors multiplied by 10**18 uint256 public nonAccreditedLimitUSD; - // Overrides for default limit in USD for non-accredited investors multiplied by 10**18 - mapping (address => uint256) public nonAccreditedLimitUSDOverride; - // Minimum investable amount in USD uint256 public minimumInvestmentUSD; @@ -87,4 +97,4 @@ contract USDTieredSTOStorage { // Array of Tiers Tier[] public tiers; -} \ No newline at end of file +} diff --git a/test/p_usd_tiered_sto.js b/test/p_usd_tiered_sto.js index 5fad46f6f..ae1fbbbb0 100644 --- a/test/p_usd_tiered_sto.js +++ b/test/p_usd_tiered_sto.js @@ -1408,20 +1408,31 @@ contract("USDTieredSTO", accounts => { it("should successfully modify accredited addresses for first STO", async () => { let stoId = 0; - - let status1 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); - assert.equal(status1, false, "Initial accreditation is set to true"); + let investorStatus = await I_USDTieredSTO_Array[stoId].investors.call(NONACCREDITED1); + let status1 = investorStatus[0].toNumber(); + assert.equal(status1, 0, "Initial accreditation is set to true"); await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1], [true], { from: ISSUER }); - let status2 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); - assert.equal(status2, true, "Failed to set single address"); + investorStatus = await I_USDTieredSTO_Array[stoId].investors.call(NONACCREDITED1); + let status2 = investorStatus[0].toNumber(); + assert.equal(status2, 1, "Failed to set single address"); await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [false, true], { from: ISSUER }); - let status3 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); - assert.equal(status3, false, "Failed to set multiple addresses"); - let status4 = await I_USDTieredSTO_Array[stoId].accredited.call(ACCREDITED1); - assert.equal(status4, true, "Failed to set multiple addresses"); - + investorStatus = await I_USDTieredSTO_Array[stoId].investors.call(NONACCREDITED1); + let status3 = investorStatus[0].toNumber(); + assert.equal(status3, 0, "Failed to set multiple addresses"); + investorStatus = await I_USDTieredSTO_Array[stoId].investors.call(ACCREDITED1); + let status4 = investorStatus[0].toNumber(); + assert.equal(status4, 1, "Failed to set multiple addresses"); + + let totalStatus = await I_USDTieredSTO_Array[stoId].getAccreditedData.call(); + + assert.equal(totalStatus[0][0], NONACCREDITED1, "Account match"); + assert.equal(totalStatus[0][1], ACCREDITED1, "Account match"); + assert.equal(totalStatus[1][0], false, "Account match"); + assert.equal(totalStatus[1][1], true, "Account match"); + assert.equal(totalStatus[2][0].toNumber(), 0, "override match"); + assert.equal(totalStatus[2][1].toNumber(), 0, "override match"); await catchRevert(I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [true], { from: ISSUER })); }); @@ -1429,10 +1440,12 @@ contract("USDTieredSTO", accounts => { let stoId = 1; await I_USDTieredSTO_Array[stoId].changeAccredited([NONACCREDITED1, ACCREDITED1], [false, true], { from: ISSUER }); - let status1 = await I_USDTieredSTO_Array[stoId].accredited.call(NONACCREDITED1); - let status2 = await I_USDTieredSTO_Array[stoId].accredited.call(ACCREDITED1); - assert.equal(status1, false, "Failed to set multiple address"); - assert.equal(status2, true, "Failed to set multiple address"); + let investorStatus = await I_USDTieredSTO_Array[stoId].investors.call(NONACCREDITED1); + let status1 = investorStatus[0].toNumber(); + investorStatus = await I_USDTieredSTO_Array[stoId].investors.call(ACCREDITED1); + let status2 = investorStatus[0].toNumber(); + assert.equal(status1, 0, "Failed to set multiple address"); + assert.equal(status2, 1, "Failed to set multiple address"); }); }); @@ -2141,14 +2154,25 @@ contract("USDTieredSTO", accounts => { await I_USDTieredSTO_Array[stoId].changeNonAccreditedLimit([NONACCREDITED1], [_nonAccreditedLimitUSD[stoId].div(2)], { from: ISSUER }); - console.log("Current limit: " + (await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSDOverride(NONACCREDITED1)).toNumber()); + let investorStatus = await I_USDTieredSTO_Array[stoId].investors.call(NONACCREDITED1); + console.log("Current limit: " + investorStatus[2].toNumber()); + let totalStatus = await I_USDTieredSTO_Array[stoId].getAccreditedData.call(); + + assert.equal(totalStatus[0][0], NONACCREDITED1, "Account match"); + assert.equal(totalStatus[0][1], ACCREDITED1, "Account match"); + assert.equal(totalStatus[1][0], false, "Account match"); + assert.equal(totalStatus[1][1], true, "Account match"); + assert.equal(totalStatus[2][0].toNumber(), _nonAccreditedLimitUSD[stoId].div(2), "override match"); + assert.equal(totalStatus[2][1].toNumber(), 0, "override match"); + }); it("should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap", async () => { let stoId = 0; let tierId = 0; - let investment_USD = await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSDOverride(NONACCREDITED1); //_nonAccreditedLimitUSD[stoId]; + let investorStatus = await I_USDTieredSTO_Array[stoId].investors.call(NONACCREDITED1); + let investment_USD = investorStatus[2];//await I_USDTieredSTO_Array[stoId].nonAccreditedLimitUSDOverride(NONACCREDITED1); //_nonAccreditedLimitUSD[stoId]; let investment_Token = await convert(stoId, tierId, false, "USD", "TOKEN", investment_USD); let investment_ETH = await convert(stoId, tierId, false, "USD", "ETH", investment_USD); let investment_POLY = await convert(stoId, tierId, false, "USD", "POLY", investment_USD);