add whitelist
This commit is contained in:
parent
3bbd8f0887
commit
a8810b5619
103
README.md
103
README.md
|
@ -27,57 +27,99 @@ solidity_flattener --solc-paths=zeppelin-solidity=$(pwd)/node_modules/zeppelin-s
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
"1510291574","1610291574","100000000000000000000","100000000000000000","0x0039f22efb07a647557c7c5d17854cfd6d489ef3"
|
"1510291574","1610291574","100000000000000000000","100000000000000000","0x0039f22efb07a647557c7c5d17854cfd6d489ef3"
|
||||||
|
|
||||||
startTime: `Friday, November 10, 2017 5:26:14 AM `
|
startTime: `Friday, November 10, 2017 5:26:14 AM `
|
||||||
endTime: `Sunday, January 10, 2021 3:12:54 PM `
|
endTime: `Sunday, January 10, 2021 3:12:54 PM `
|
||||||
cap: `100 eth `
|
cap: `100 eth `
|
||||||
minimum: `0.1 eth `
|
minimum: `0.1 eth `
|
||||||
vault: `0x0039f22efb07a647557c7c5d17854cfd6d489ef3`
|
vault: `0x0039f22efb07a647557c7c5d17854cfd6d489ef3`
|
||||||
4. Let investors send money to contract's address OR to send to `buy` method (`0xa6f2ae3a`)
|
4. Whitelist investors by calling `whitelistInvestors` with an array ['0x0039f22efb07a647557c7c5d17854cfd6d489ef3']
|
||||||
|
5. Let whitelisted investors send money to contract's address OR to send to `buy` method (`0xa6f2ae3a`)
|
||||||
|
|
||||||
|
# How to whitelist a lot of addresses in batch
|
||||||
|
1. `cd scripts`
|
||||||
|
2. `npm install`
|
||||||
|
3. open `.env` file and modify settings:
|
||||||
```
|
```
|
||||||
Contract: Presale
|
PRESALE_ADDRESS=0x6F3f79941f89E03D4aF9bDb8BE0623DC24F2bef0
|
||||||
|
UNLOCKED_ADDRESS=0x0039f22efb07a647557c7c5d17854cfd6d489ef3
|
||||||
|
RPC_PORT=8549
|
||||||
|
GAS_PRICE=0.7
|
||||||
|
```
|
||||||
|
4. run parity with unlocked account from which the deployment will happen. It has to match with your .env UNLOCKED_ADDRESS:
|
||||||
|
```
|
||||||
|
parity --jsonrpc-port 8549 --chain kovan --unlock 0x0039F22efB07A647557C7C5d17854CFD6D489eF3 --password $HOME/FILE_PATH_TO_YOUR_PASSWORD_FILE
|
||||||
|
```
|
||||||
|
4. run `node whitelist.js`
|
||||||
|
|
||||||
|
# Test result and gas usage
|
||||||
|
```
|
||||||
|
|
||||||
|
Contract: Presale
|
||||||
✓ constructor should set owner
|
✓ constructor should set owner
|
||||||
✓ can not buy if not initialized (22623 gas)
|
✓ can not buy if not initialized (21411 gas)
|
||||||
#initilize
|
#initilize
|
||||||
✓ rejects if not sent by owner (25358 gas)
|
✓ rejects if not sent by owner (25424 gas)
|
||||||
✓ sets values (131519 gas)
|
✓ sets values (131614 gas)
|
||||||
✓ cannot initialize twice (157189 gas)
|
✓ cannot initialize twice (157350 gas)
|
||||||
✓ startTime cannot be 0 (25102 gas)
|
✓ startTime cannot be 0 (25168 gas)
|
||||||
✓ endTime cannot be 0 (25166 gas)
|
✓ endTime cannot be 0 (25232 gas)
|
||||||
✓ endTime cannot be less than startTime (25358 gas)
|
✓ endTime cannot be less than startTime (25424 gas)
|
||||||
✓ cap cannot be 0 (24910 gas)
|
✓ cap cannot be 0 (24976 gas)
|
||||||
✓ vault cannot be 0x0 (24078 gas)
|
✓ vault cannot be 0x0 (24144 gas)
|
||||||
✓ minimumContribution cannot be 0 (24910 gas)
|
✓ minimumContribution cannot be 0 (24976 gas)
|
||||||
#buy
|
#buy
|
||||||
✓ cannot buy if not value is 0 (64231 gas)
|
✓ cannot buy if not whitelisted (21411 gas)
|
||||||
✓ cannot buy if not value is less than minimum (64231 gas)
|
✓ cannot buy if not value is 0 (63333 gas)
|
||||||
✓ can not buy if time is not within startTime&endTime (116233 gas)
|
✓ cannot buy if not value is less than minimum (63333 gas)
|
||||||
✓ can not buy more than cap (64236 gas)
|
✓ can not buy if time is not within startTime&endTime (111666 gas)
|
||||||
✓ happy path (178974 gas)
|
✓ can not buy more than cap (63333 gas)
|
||||||
|
✓ happy path (244544 gas)
|
||||||
|
whitelisting capabilities
|
||||||
|
#whitelistInvestor
|
||||||
|
✓ cannot by called by non-owner (23450 gas)
|
||||||
|
✓ whitelists an investor (64399 gas)
|
||||||
|
#whitelistInvestors
|
||||||
|
✓ cannot by called by non-owner (23666 gas)
|
||||||
|
✓ whitelists investors (119844 gas)
|
||||||
|
#blacklistInvestor
|
||||||
|
✓ cannot by called by non-owner (23582 gas)
|
||||||
|
✓ blacklist an investors (139579 gas)
|
||||||
|
|
||||||
·-----------------------------------------------------------------------|-----------------------------------·
|
·------------------------------------------------------------------------|-----------------------------------·
|
||||||
│ Gas · Block limit: 17592186044415 gas │
|
│ Gas · Block limit: 17592186044415 gas │
|
||||||
·········································|······························|····································
|
··········································|······························|····································
|
||||||
│ Methods · 1 gwei/gas · 297.51 usd/eth │
|
│ Methods · 1 gwei/gas · 307.55 usd/eth │
|
||||||
···················|·····················|·········|··········|·········|················|···················
|
···················|······················|·········|··········|·········|················|···················
|
||||||
│ Contract · Method · Min · Max · Avg · # calls · usd (avg) │
|
│ Contract · Method · Min · Max · Avg · # calls · usd (avg) │
|
||||||
···················|·····················|·········|··········|·········|················|···················
|
···················|······················|·········|··········|·········|················|···················
|
||||||
|
│ PresaleOracles · blacklistInvestor · 19735 · 23582 · 21659 · 2 · 0.01 │
|
||||||
|
···················|······················|·········|··········|·········|················|···················
|
||||||
│ PresaleOracles · buy · - · - · - · 0 · - │
|
│ PresaleOracles · buy · - · - · - · 0 · - │
|
||||||
···················|·····················|·········|··········|·········|················|···················
|
···················|······················|·········|··········|·········|················|···················
|
||||||
│ PresaleOracles · claimTokens · - · - · - · 0 · - │
|
│ PresaleOracles · claimTokens · - · - · - · 0 · - │
|
||||||
···················|·····················|·········|··········|·········|················|···················
|
···················|······················|·········|··········|·········|················|···················
|
||||||
│ PresaleOracles · initialize · 24078 · 131519 · 46359 · 10 · 0.01 │
|
│ PresaleOracles · initialize · 24144 · 131614 · 46431 · 10 · 0.01 │
|
||||||
···················|·····················|·········|··········|·········|················|···················
|
···················|······················|·········|··········|·········|················|···················
|
||||||
│ PresaleOracles · Presale · - · - · - · 0 · - │
|
│ PresaleOracles · Presale · - · - · - · 0 · - │
|
||||||
···················|·····················|·········|··········|·········|················|···················
|
···················|······················|·········|··········|·········|················|···················
|
||||||
│ PresaleOracles · transferOwnership · - · - · - · 0 · - │
|
│ PresaleOracles · transferOwnership · - · - · - · 0 · - │
|
||||||
·------------------|---------------------|---------|----------|---------|----------------|------------------·
|
···················|······················|·········|··········|·········|················|···················
|
||||||
|
│ PresaleOracles · whitelistInvestor · 23450 · 64399 · 50749 · 3 · 0.02 │
|
||||||
|
···················|······················|·········|··········|·········|················|···················
|
||||||
|
│ PresaleOracles · whitelistInvestors · 23666 · 119844 · 87785 · 3 · 0.03 │
|
||||||
|
·------------------|----------------------|---------|----------|---------|----------------|------------------·
|
||||||
|
|
||||||
16 passing (2m)
|
23 passing (3m)
|
||||||
```
|
```
|
||||||
# Testnet deployment
|
# Testnet deployment
|
||||||
|
|
||||||
|
=====
|
||||||
|
## Latest Contract deployment
|
||||||
|
https://kovan.etherscan.io/address/0x6f3f79941f89e03d4af9bdb8be0623dc24f2bef0
|
||||||
|
=====
|
||||||
|
|
||||||
|
## Previous deployments with old source code:
|
||||||
|
|
||||||
Contract Deployment: https://kovan.etherscan.io/address/0xb9b49e21e77d2d89a9e4c7ef4f684ad2a4e99663#code
|
Contract Deployment: https://kovan.etherscan.io/address/0xb9b49e21e77d2d89a9e4c7ef4f684ad2a4e99663#code
|
||||||
|
|
||||||
Called Initialize by Owner with params:
|
Called Initialize by Owner with params:
|
||||||
|
@ -116,4 +158,3 @@ https://kovan.etherscan.io/address/0xec1afb89f87cb0ac296cad6e73dbeeab5b006050#re
|
||||||
|
|
||||||
Send 0.1 ether to get rejected:
|
Send 0.1 ether to get rejected:
|
||||||
https://kovan.etherscan.io/tx/0xd859be5b5b58303a4cbc61902f8927efa9de96a3739ce39a18e1f6949a154c2b
|
https://kovan.etherscan.io/tx/0xd859be5b5b58303a4cbc61902f8927efa9de96a3739ce39a18e1f6949a154c2b
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ contract PresaleOracles is Ownable {
|
||||||
uint256 public totalInvestedInWei;
|
uint256 public totalInvestedInWei;
|
||||||
uint256 public minimumContribution;
|
uint256 public minimumContribution;
|
||||||
mapping(address => uint256) public investorBalances;
|
mapping(address => uint256) public investorBalances;
|
||||||
|
mapping(address => bool) public whitelist;
|
||||||
|
uint256 public investorsLength;
|
||||||
address public vault;
|
address public vault;
|
||||||
bool public isInitialized = false;
|
bool public isInitialized = false;
|
||||||
// TESTED by Roman Storm
|
// TESTED by Roman Storm
|
||||||
|
@ -46,6 +48,7 @@ contract PresaleOracles is Ownable {
|
||||||
}
|
}
|
||||||
//TESTED by Roman Storm
|
//TESTED by Roman Storm
|
||||||
function buy() public payable {
|
function buy() public payable {
|
||||||
|
require(whitelist[msg.sender]);
|
||||||
require(isValidPurchase(msg.value));
|
require(isValidPurchase(msg.value));
|
||||||
require(isInitialized);
|
require(isInitialized);
|
||||||
require(getTime() >= startTime && getTime() <= endTime);
|
require(getTime() >= startTime && getTime() <= endTime);
|
||||||
|
@ -81,4 +84,30 @@ contract PresaleOracles is Ownable {
|
||||||
bool withinCap = totalInvestedInWei.add(_amount) <= cap;
|
bool withinCap = totalInvestedInWei.add(_amount) <= cap;
|
||||||
return hasMinimumAmount && withinCap && nonZero;
|
return hasMinimumAmount && withinCap && nonZero;
|
||||||
}
|
}
|
||||||
|
//TESTED by Roman Storm
|
||||||
|
function whitelistInvestor(address _newInvestor) public onlyOwner {
|
||||||
|
if(!whitelist[_newInvestor]) {
|
||||||
|
whitelist[_newInvestor] = true;
|
||||||
|
investorsLength++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TESTED by Roman Storm
|
||||||
|
function whitelistInvestors(address[] _investors) external onlyOwner {
|
||||||
|
require(_investors.length <= 250);
|
||||||
|
for(uint8 i=0; i<_investors.length;i++) {
|
||||||
|
address newInvestor = _investors[i];
|
||||||
|
if(!whitelist[newInvestor]) {
|
||||||
|
whitelist[newInvestor] = true;
|
||||||
|
investorsLength++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function blacklistInvestor(address _investor) public onlyOwner {
|
||||||
|
if(whitelist[_investor]) {
|
||||||
|
delete whitelist[_investor];
|
||||||
|
if(investorsLength != 0) {
|
||||||
|
investorsLength--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -115,6 +115,8 @@ contract PresaleOracles is Ownable {
|
||||||
uint256 public totalInvestedInWei;
|
uint256 public totalInvestedInWei;
|
||||||
uint256 public minimumContribution;
|
uint256 public minimumContribution;
|
||||||
mapping(address => uint256) public investorBalances;
|
mapping(address => uint256) public investorBalances;
|
||||||
|
mapping(address => bool) public whitelist;
|
||||||
|
uint256 public investorsLength;
|
||||||
address public vault;
|
address public vault;
|
||||||
bool public isInitialized = false;
|
bool public isInitialized = false;
|
||||||
// TESTED by Roman Storm
|
// TESTED by Roman Storm
|
||||||
|
@ -143,6 +145,7 @@ contract PresaleOracles is Ownable {
|
||||||
}
|
}
|
||||||
//TESTED by Roman Storm
|
//TESTED by Roman Storm
|
||||||
function buy() public payable {
|
function buy() public payable {
|
||||||
|
require(whitelist[msg.sender]);
|
||||||
require(isValidPurchase(msg.value));
|
require(isValidPurchase(msg.value));
|
||||||
require(isInitialized);
|
require(isInitialized);
|
||||||
require(getTime() >= startTime && getTime() <= endTime);
|
require(getTime() >= startTime && getTime() <= endTime);
|
||||||
|
@ -178,5 +181,31 @@ contract PresaleOracles is Ownable {
|
||||||
bool withinCap = totalInvestedInWei.add(_amount) <= cap;
|
bool withinCap = totalInvestedInWei.add(_amount) <= cap;
|
||||||
return hasMinimumAmount && withinCap && nonZero;
|
return hasMinimumAmount && withinCap && nonZero;
|
||||||
}
|
}
|
||||||
|
//TESTED by Roman Storm
|
||||||
|
function whitelistInvestor(address _newInvestor) public onlyOwner {
|
||||||
|
if(!whitelist[_newInvestor]) {
|
||||||
|
whitelist[_newInvestor] = true;
|
||||||
|
investorsLength++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TESTED by Roman Storm
|
||||||
|
function whitelistInvestors(address[] _investors) external onlyOwner {
|
||||||
|
require(_investors.length <= 250);
|
||||||
|
for(uint8 i=0; i<_investors.length;i++) {
|
||||||
|
address newInvestor = _investors[i];
|
||||||
|
if(!whitelist[newInvestor]) {
|
||||||
|
whitelist[newInvestor] = true;
|
||||||
|
investorsLength++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function blacklistInvestor(address _investor) public onlyOwner {
|
||||||
|
if(whitelist[_investor]) {
|
||||||
|
delete whitelist[_investor];
|
||||||
|
if(investorsLength != 0) {
|
||||||
|
investorsLength--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
PRESALE_ADDRESS=0x6F3f79941f89E03D4aF9bDb8BE0623DC24F2bef0
|
||||||
|
UNLOCKED_ADDRESS=0x0039f22efb07a647557c7c5d17854cfd6d489ef3
|
||||||
|
RPC_PORT=8549
|
||||||
|
GAS_PRICE=0.7
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,62 @@
|
||||||
|
require('dotenv').config();
|
||||||
|
const ContributionABI = require('../build/contracts/PresaleOracles.json').abi;
|
||||||
|
|
||||||
|
// const Web3 = require('web3');
|
||||||
|
// // const MAINET_RPC_URL = 'https://mainnet.infura.io/metamask'
|
||||||
|
// // const KOVAN_RPC_URL = 'https://kovan.infura.io/metamask'
|
||||||
|
// const local = `http://localhost:${process.env.RPC_PORT}`;
|
||||||
|
// const provider = new Web3.providers.HttpProvider(local);
|
||||||
|
// const web3 = new Web3(provider);
|
||||||
|
// var myContract = new web3.eth.Contract(ContributionABI, '0x6F3f79941f89E03D4aF9bDb8BE0623DC24F2bef0');
|
||||||
|
// const ARRAY_OF_ADDRESSES = require('./ARRAY_OF_ADDRESSES.json');
|
||||||
|
// filterAddresses(ARRAY_OF_ADDRESSES).then(console.log)
|
||||||
|
function setup({web3Param, contribAddress}){
|
||||||
|
web3 = web3Param;
|
||||||
|
CONTRIBUTION_ADDRESS = contribAddress
|
||||||
|
myContract = new web3.eth.Contract(ContributionABI, CONTRIBUTION_ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readCap() {
|
||||||
|
myContract.methods.cap().call().then((cap) => {
|
||||||
|
console.log('cap', cap);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function isWhitelisted(toCheckAddress) {
|
||||||
|
readCap();
|
||||||
|
var count = 0;
|
||||||
|
var leftRun = toCheckAddress.length;
|
||||||
|
let notWhitelisted = [];
|
||||||
|
let promise = new Promise((res) => {
|
||||||
|
if(toCheckAddress.length === 0 || !toCheckAddress) {
|
||||||
|
rej('array is empty');
|
||||||
|
}
|
||||||
|
console.log(toCheckAddress.length)
|
||||||
|
toCheckAddress.forEach((address, index) => {
|
||||||
|
myContract.methods.whitelist(address).call().then((isWhitelisted) => {
|
||||||
|
leftRun--;
|
||||||
|
if (!isWhitelisted) {
|
||||||
|
count++;
|
||||||
|
notWhitelisted.push(address);
|
||||||
|
}
|
||||||
|
if (leftRun === 0) {
|
||||||
|
console.log('FINISHED! notWhitelisted: ', notWhitelisted.length);
|
||||||
|
res(notWhitelisted);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterAddresses(arrayOfAddresses) {
|
||||||
|
const date = Date.now();
|
||||||
|
console.log(date, 'DATE NOW', arrayOfAddresses.length);
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
return isWhitelisted(arrayOfAddresses).then((whitelistedAddress) => {
|
||||||
|
res(whitelistedAddress);
|
||||||
|
}).catch(console.error);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
exports.filterAddresses = filterAddresses;
|
||||||
|
exports.isWhitelisted = isWhitelisted;
|
||||||
|
exports.setup = setup;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "scripts",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "whitelist.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Roman Storm",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"dotenv": "^4.0.0",
|
||||||
|
"web3": "^1.0.0-beta.24"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
require('dotenv').config();
|
||||||
|
const ARRAY_OF_ADDRESSES = require('./ARRAY_OF_ADDRESSES.json');
|
||||||
|
const RPC_PORT = process.env.RPC_PORT;
|
||||||
|
const PRESALE_ADDRESS = process.env.PRESALE_ADDRESS;
|
||||||
|
const UNLOCKED_ADDRESS = process.env.UNLOCKED_ADDRESS;
|
||||||
|
|
||||||
|
const ICO_ABI = require('../build/contracts/PresaleOracles.json').abi;
|
||||||
|
const Web3 = require('web3');
|
||||||
|
const provider = new Web3.providers.HttpProvider(`http://localhost:${RPC_PORT}`);
|
||||||
|
const web3 = new Web3(provider);
|
||||||
|
|
||||||
|
const { filterAddresses, setup } = require('./filterAddresses');
|
||||||
|
setup({ web3Param: web3, contribAddress: PRESALE_ADDRESS});
|
||||||
|
filterAddresses(ARRAY_OF_ADDRESSES).then(async (toWhitelist) => {
|
||||||
|
console.log(toWhitelist.length);
|
||||||
|
const addPerTx = 160;
|
||||||
|
const slices = Math.ceil(toWhitelist.length / addPerTx);
|
||||||
|
var txcount = await web3.eth.getTransactionCount(UNLOCKED_ADDRESS);
|
||||||
|
const nonce = web3.utils.toHex(txcount);
|
||||||
|
console.log('STARTED', nonce);
|
||||||
|
return sendTransactionToContribution({array: toWhitelist, slice: slices, addPerTx, nonce});
|
||||||
|
}).then(console.log).catch(console.error);
|
||||||
|
|
||||||
|
const GAS_PRICE = web3.utils.toWei(process.env.GAS_PRICE, 'gwei');
|
||||||
|
const GAS_LIMIT = '6700000';
|
||||||
|
const myContract = new web3.eth.Contract(ICO_ABI, PRESALE_ADDRESS, {
|
||||||
|
from: UNLOCKED_ADDRESS, // default from address
|
||||||
|
gasPrice: GAS_PRICE,
|
||||||
|
gas: GAS_LIMIT // default gas price in wei
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
async function sendTransactionToContribution({array, slice, addPerTx, nonce}) {
|
||||||
|
if(array.length === 0){
|
||||||
|
console.log('array doesnot have not whitelisted addresses');
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
const start = (slice - 1) * addPerTx;
|
||||||
|
const end = slice * addPerTx;
|
||||||
|
const arrayToProcess = array.slice(start, end);
|
||||||
|
let encodedData = myContract.methods.whitelistInvestors(arrayToProcess).encodeABI();
|
||||||
|
|
||||||
|
console.log('Processing array length', arrayToProcess.length, arrayToProcess[0], arrayToProcess[arrayToProcess.length - 1]);
|
||||||
|
return new Promise((res) => {
|
||||||
|
web3.eth.estimateGas({
|
||||||
|
from: UNLOCKED_ADDRESS, to: PRESALE_ADDRESS, data: encodedData, gas: GAS_LIMIT, gasPrice: GAS_PRICE
|
||||||
|
}).then((gasNeeded) => {
|
||||||
|
console.log('gasNeeded', gasNeeded);
|
||||||
|
web3.eth.sendTransaction({
|
||||||
|
from: UNLOCKED_ADDRESS, to: PRESALE_ADDRESS, data: encodedData, gas: gasNeeded, gasPrice: GAS_PRICE, nonce
|
||||||
|
}).on('transactionHash', function(hash){console.log('hash', hash)});
|
||||||
|
slice--;
|
||||||
|
if (slice > 0) {
|
||||||
|
nonce = parseInt(nonce, 16);
|
||||||
|
nonce++;
|
||||||
|
nonce = web3.utils.toHex(nonce);
|
||||||
|
sendTransactionToContribution({array, slice, addPerTx, nonce});
|
||||||
|
} else {
|
||||||
|
res({ result: 'completed' });
|
||||||
|
// process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
|
@ -112,6 +112,11 @@ contract('Presale', function(accounts) {
|
||||||
PRESALE_END_DATE = moment('2017-12-18T16:00:00Z').unix();
|
PRESALE_END_DATE = moment('2017-12-18T16:00:00Z').unix();
|
||||||
await presaleContract.initialize(PRESALE_START_DATE, PRESALE_END_DATE, ETHER.mul(40000), ETHER.mul(100), accounts[1], {from: accounts[0]})
|
await presaleContract.initialize(PRESALE_START_DATE, PRESALE_END_DATE, ETHER.mul(40000), ETHER.mul(100), accounts[1], {from: accounts[0]})
|
||||||
})
|
})
|
||||||
|
it('cannot buy if not whitelisted', async () => {
|
||||||
|
// require(whitelist[msg.sender]);
|
||||||
|
await presaleContract.sendTransaction({amount: ETHER})
|
||||||
|
.should.be.rejectedWith(REVERT_MSG);
|
||||||
|
})
|
||||||
it('cannot buy if not value is 0', async () => {
|
it('cannot buy if not value is 0', async () => {
|
||||||
// require(msg.value > 0);
|
// require(msg.value > 0);
|
||||||
await presaleContract.setTime(PRESALE_START_DATE);
|
await presaleContract.setTime(PRESALE_START_DATE);
|
||||||
|
@ -150,6 +155,7 @@ contract('Presale', function(accounts) {
|
||||||
const vault = accounts[1];
|
const vault = accounts[1];
|
||||||
const preVaultBalance = await web3.eth.getBalance(vault);
|
const preVaultBalance = await web3.eth.getBalance(vault);
|
||||||
await presaleContract.setTime(PRESALE_START_DATE);
|
await presaleContract.setTime(PRESALE_START_DATE);
|
||||||
|
await presaleContract.whitelistInvestor(accounts[0]);
|
||||||
await presaleContract.sendTransaction({value: ETHER.mul(100)});
|
await presaleContract.sendTransaction({value: ETHER.mul(100)});
|
||||||
ETHER.mul(100).should.be.bignumber.equal(
|
ETHER.mul(100).should.be.bignumber.equal(
|
||||||
await presaleContract.investorBalances(accounts[0])
|
await presaleContract.investorBalances(accounts[0])
|
||||||
|
@ -177,5 +183,78 @@ contract('Presale', function(accounts) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('whitelisting capabilities', async ()=> {
|
||||||
|
describe('#whitelistInvestor', async ()=>{
|
||||||
|
it('cannot by called by non-owner', async ()=> {
|
||||||
|
await presaleContract.whitelistInvestor(accounts[0], {from: accounts[1]})
|
||||||
|
.should.be.rejectedWith(REVERT_MSG);
|
||||||
|
})
|
||||||
|
it('whitelists an investor', async ()=> {
|
||||||
|
'0'.should.be.bignumber.equal(
|
||||||
|
await presaleContract.investorsLength()
|
||||||
|
)
|
||||||
|
false.should.be.equal(
|
||||||
|
await presaleContract.whitelist(accounts[0])
|
||||||
|
)
|
||||||
|
await presaleContract.whitelistInvestor(accounts[0]);
|
||||||
|
true.should.be.equal(
|
||||||
|
await presaleContract.whitelist(accounts[0])
|
||||||
|
)
|
||||||
|
'1'.should.be.bignumber.equal(
|
||||||
|
await presaleContract.investorsLength()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#whitelistInvestors', async ()=>{
|
||||||
|
it('cannot by called by non-owner', async ()=> {
|
||||||
|
await presaleContract.whitelistInvestors([accounts[0]], {from: accounts[1]})
|
||||||
|
.should.be.rejectedWith(REVERT_MSG);
|
||||||
|
})
|
||||||
|
it('whitelists investors', async ()=> {
|
||||||
|
'0'.should.be.bignumber.equal(
|
||||||
|
await presaleContract.investorsLength()
|
||||||
|
)
|
||||||
|
false.should.be.equal(
|
||||||
|
await presaleContract.whitelist(accounts[0])
|
||||||
|
)
|
||||||
|
await presaleContract.whitelistInvestors([accounts[0], accounts[1], accounts[2]]);
|
||||||
|
true.should.be.equal(
|
||||||
|
await presaleContract.whitelist(accounts[2])
|
||||||
|
)
|
||||||
|
'3'.should.be.bignumber.equal(
|
||||||
|
await presaleContract.investorsLength()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#blacklistInvestor', async ()=>{
|
||||||
|
it('cannot by called by non-owner', async ()=> {
|
||||||
|
await presaleContract.blacklistInvestor(accounts[0], {from: accounts[1]})
|
||||||
|
.should.be.rejectedWith(REVERT_MSG);
|
||||||
|
})
|
||||||
|
it('blacklist an investors', async ()=> {
|
||||||
|
'0'.should.be.bignumber.equal(
|
||||||
|
await presaleContract.investorsLength()
|
||||||
|
)
|
||||||
|
false.should.be.equal(
|
||||||
|
await presaleContract.whitelist(accounts[0])
|
||||||
|
)
|
||||||
|
await presaleContract.whitelistInvestors([accounts[0], accounts[1], accounts[2]]);
|
||||||
|
true.should.be.equal(
|
||||||
|
await presaleContract.whitelist(accounts[0])
|
||||||
|
)
|
||||||
|
'3'.should.be.bignumber.equal(
|
||||||
|
await presaleContract.investorsLength()
|
||||||
|
)
|
||||||
|
await presaleContract.blacklistInvestor(accounts[0]);
|
||||||
|
false.should.be.equal(
|
||||||
|
await presaleContract.whitelist(accounts[0])
|
||||||
|
)
|
||||||
|
'2'.should.be.bignumber.equal(
|
||||||
|
await presaleContract.investorsLength()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
Loading…
Reference in New Issue