Skip to content

Commit

Permalink
Merge 807de45 into 028a95b
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdossa authored Sep 4, 2018
2 parents 028a95b + 807de45 commit 2b2904a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 7 deletions.
30 changes: 26 additions & 4 deletions contracts/modules/STO/USDTieredSTO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,12 @@ contract USDTieredSTO is ISTO, ReentrancyGuard {
// List of accredited investors
mapping (address => bool) public accredited;

// Limit in USD for non-accredited investors multiplied by 10**18
// 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;

Expand All @@ -102,6 +105,8 @@ contract USDTieredSTO is ISTO, ReentrancyGuard {
////////////

event SetAllowBeneficialInvestments(bool _allowed);
event SetNonAccreditedLimit(address _investor, uint256 _limit);
event SetAccredited(address _investor, bool _accredited);
event TokenPurchase(address indexed _purchaser, address indexed _beneficiary, uint256 _tokens, uint256 _usdAmount, uint256 _tierPrice, uint8 _tier);
event FundsReceivedETH(address indexed _purchaser, address indexed _beneficiary, uint256 _usdAmount, uint256 _receivedValue, uint256 _spentValue, uint256 _rate);
event FundsReceivedPOLY(address indexed _purchaser, address indexed _beneficiary, uint256 _usdAmount, uint256 _receivedValue, uint256 _spentValue, uint256 _rate);
Expand Down Expand Up @@ -331,6 +336,22 @@ contract USDTieredSTO is ISTO, ReentrancyGuard {
require(_investors.length == _accredited.length);
for (uint256 i = 0; i < _investors.length; i++) {
accredited[_investors[i]] = _accredited[i];
emit SetAccredited(_investors[i], _accredited[i]);
}
}

/**
* @notice Modify the list of overrides for non-accredited limits in USD
* @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 {
//nonAccreditedLimitUSDOverride
require(_investors.length == _nonAccreditedLimit.length);
for (uint256 i = 0; i < _investors.length; i++) {
require(_nonAccreditedLimit[i] > 0, "Limit cannot be 0");
nonAccreditedLimitUSDOverride[_investors[i]] = _nonAccreditedLimit[i];
emit SetNonAccreditedLimit(_investors[i], _nonAccreditedLimit[i]);
}
}

Expand Down Expand Up @@ -409,9 +430,10 @@ contract USDTieredSTO is ISTO, ReentrancyGuard {

// Check for non-accredited cap
if (!accredited[_beneficiary]) {
require(investorInvestedUSD[_beneficiary] < nonAccreditedLimitUSD, "Non-accredited investor has already reached nonAccreditedLimitUSD");
if (investedUSD.add(investorInvestedUSD[_beneficiary]) > nonAccreditedLimitUSD)
investedUSD = nonAccreditedLimitUSD.sub(investorInvestedUSD[_beneficiary]);
uint256 investorLimitUSD = (nonAccreditedLimitUSDOverride[_beneficiary] == 0) ? nonAccreditedLimitUSD : nonAccreditedLimitUSDOverride[_beneficiary];
require(investorInvestedUSD[_beneficiary] < investorLimitUSD, "Non-accredited investor has already reached nonAccreditedLimitUSD");
if (investedUSD.add(investorInvestedUSD[_beneficiary]) > investorLimitUSD)
investedUSD = investorLimitUSD.sub(investorInvestedUSD[_beneficiary]);
}

uint256 spentUSD;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ contract ManualApprovalTransferManager is ITransferManager {
* @param _expiryTime is the time until which the transfer is allowed
*/
function addManualApproval(address _from, address _to, uint256 _allowance, uint256 _expiryTime) public withPerm(TRANSFER_APPROVAL) {
//Passing a _expiryTime == 0 into this function, is equivalent to removing the manual approval.
require(_from != address(0), "Invalid from address");
require(_to != address(0), "Invalid to address");
require(_expiryTime > now, "Invalid expiry time");
require(manualApprovals[_from][_to].allowance == 0, "Approval already exists");
manualApprovals[_from][_to] = ManualApproval(_allowance, _expiryTime);
emit LogAddManualApproval(_from, _to, _allowance, _expiryTime, msg.sender);
}
Expand All @@ -137,10 +137,10 @@ contract ManualApprovalTransferManager is ITransferManager {
* @param _expiryTime is the time until which the transfer is blocked
*/
function addManualBlocking(address _from, address _to, uint256 _expiryTime) public withPerm(TRANSFER_APPROVAL) {
//Passing a _expiryTime == 0 into this function, is equivalent to removing the manual blocking.
require(_from != address(0), "Invalid from address");
require(_to != address(0), "Invalid to address");
require(_expiryTime > now, "Invalid expiry time");
require(manualApprovals[_from][_to].expiryTime == 0, "Blocking already exists");
manualBlockings[_from][_to] = ManualBlocking(_expiryTime);
emit LogAddManualBlocking(_from, _to, _expiryTime, msg.sender);
}
Expand Down
12 changes: 11 additions & 1 deletion test/q_usd_tiered_sto.js
Original file line number Diff line number Diff line change
Expand Up @@ -1563,11 +1563,19 @@ contract('USDTieredSTO', accounts => {
assert.equal((await I_USDTieredSTO_Array[stoId].investorInvestedPOLY.call(ACCREDITED1)).toNumber(), init_investorInvestedPOLY.add(investment_POLY).toNumber(), "investorInvestedPOLY not changed as expected");
});

it("should successfully modify NONACCREDITED cap for NONACCREDITED1", async() => {
let stoId = 0;
let tierId = 0;
console.log("Current investment: " + (await I_USDTieredSTO_Array[stoId].investorInvestedUSD.call(NONACCREDITED1)).toNumber());
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());
});

it("should successfully buy a partial amount and refund balance when reaching NONACCREDITED cap", async() => {
let stoId = 0;
let tierId = 0;

let investment_USD = _nonAccreditedLimitUSD[stoId];
let investment_USD = (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);
Expand All @@ -1577,6 +1585,8 @@ contract('USDTieredSTO', accounts => {
let refund_ETH = await convert(stoId, tierId, false, "USD", "ETH", refund_USD);
let refund_POLY = await convert(stoId, tierId, false, "USD", "POLY", refund_USD);

console.log("Expected refund in tokens: " + refund_Token.toNumber());

let snap = await takeSnapshot();

let init_TokenSupply = await I_SecurityToken.totalSupply();
Expand Down

0 comments on commit 2b2904a

Please sign in to comment.