Skip to content

CLI Vesting Escrow Wallet #753

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 11 commits into from
Jul 24, 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
14 changes: 13 additions & 1 deletion CLI/commands/IO/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ function readStringNonEmptyWithMaxBinarySize(maxBinarySize, message, defaultValu
});
}

function readDateInTheFuture(message, defaultValue) {
const now = Math.floor(Date.now() / 1000);
return readlineSync.question(message, {
limit: function (input) {
return parseInt(input) >= now;
},
limitMessage: `Must be a future date`,
defaultInput: defaultValue
});
}

module.exports = {
readAddress,
readMultipleAddresses,
Expand All @@ -109,5 +120,6 @@ module.exports = {
readNumberLessThanOrEqual,
readNumberBetween,
readStringNonEmpty,
readStringNonEmptyWithMaxBinarySize
readStringNonEmptyWithMaxBinarySize,
readDateInTheFuture
}
2 changes: 1 addition & 1 deletion CLI/commands/ST20Generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ async function step_token_deploy (_name, _details, _divisible) {
await approvePoly(securityTokenRegistryAddress, polyFee);
let generateSecurityTokenAction = securityTokenRegistry.methods.generateNewSecurityToken(tokenName, tokenSymbol, tokenDetails, divisibility, treasuryWallet, 0);
let receipt = await common.sendTransaction(generateSecurityTokenAction);
let event = common.getEventFromLogs(securityTokenRegistry._jsonInterface, receipt.logs, 'NewSecurityTokenCreated');
let event = common.getEventFromLogs(securityTokenRegistry._jsonInterface, receipt.logs, 'NewSecurityToken');
console.log(chalk.green(`Security Token has been successfully deployed at address ${event._securityTokenAddress}`));
}

Expand Down
3 changes: 2 additions & 1 deletion CLI/commands/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ module.exports = Object.freeze({
TRANSFER: 2,
STO: 3,
DIVIDENDS: 4,
BURN: 5
BURN: 5,
WALLET: 7
},
DURATION: {
seconds: function (val) {
Expand Down
5 changes: 5 additions & 0 deletions CLI/commands/helpers/contract_abis.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ let cappedSTOFactoryABI;
let usdTieredSTOFactoryABI;
let erc20DividendCheckpointABI;
let etherDividendCheckpointABI;
let vestingEscrowWalletABI;
let moduleInterfaceABI;
let ownableABI;
let stoABI;
Expand Down Expand Up @@ -53,6 +54,7 @@ try {
usdTieredSTOFactoryABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/USDTieredSTOFactory.json`).toString()).abi;
erc20DividendCheckpointABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/ERC20DividendCheckpoint.json`).toString()).abi;
etherDividendCheckpointABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/EtherDividendCheckpoint.json`).toString()).abi;
vestingEscrowWalletABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/VestingEscrowWallet.json`).toString()).abi;
moduleInterfaceABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/IModule.json`).toString()).abi;
ownableABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/Ownable.json`).toString()).abi;
stoABI = JSON.parse(require('fs').readFileSync(`${__dirname}/../../../build/contracts/STO.json`).toString()).abi
Expand Down Expand Up @@ -136,6 +138,9 @@ module.exports = {
etherDividendCheckpoint: function () {
return etherDividendCheckpointABI;
},
vestingEscrowWallet: function () {
return vestingEscrowWalletABI;
},
moduleInterface: function () {
return moduleInterfaceABI;
},
Expand Down
1 change: 0 additions & 1 deletion CLI/commands/permission_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ let securityTokenRegistry;
let securityToken;
let polyToken;
let currentPermissionManager;
let isNewDelegate = false;

async function executeApp() {
console.log('\n', chalk.blue('Permission Manager - Main Menu', '\n'));
Expand Down
20 changes: 17 additions & 3 deletions CLI/commands/token_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,15 @@ async function displayModules() {
let stoModules = allModules.filter(m => m.type == gbl.constants.MODULES_TYPES.STO);
let cpModules = allModules.filter(m => m.type == gbl.constants.MODULES_TYPES.DIVIDENDS);
let burnModules = allModules.filter(m => m.type == gbl.constants.MODULES_TYPES.BURN);
let walletModules = allModules.filter(m => m.type == gbl.constants.MODULES_TYPES.WALLET);

// Module Counts
let numPM = pmModules.length;
let numTM = tmModules.length;
let numSTO = stoModules.length;
let numCP = cpModules.length;
let numBURN = burnModules.length;
let numW = walletModules.length;

console.log(`
******************* Module Information ********************
Expand All @@ -115,6 +117,7 @@ async function displayModules() {
- STO: ${(numSTO > 0) ? numSTO : 'None'}
- Checkpoint: ${(numCP > 0) ? numCP : 'None'}
- Burn: ${(numBURN > 0) ? numBURN : 'None'}
- Wallet: ${(numW > 0) ? numW : 'None'}
`);

if (numPM) {
Expand All @@ -138,9 +141,14 @@ async function displayModules() {
}

if (numBURN) {
console.log(` Burn Modules:`);
console.log(`Burn Modules:`);
burnModules.map(m => console.log(`- ${m.label}: ${m.name} (${m.version}) is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`));
}

if (numW) {
console.log(`Wallet Modules:`);
walletModules.map(m => console.log(`- ${m.label}: ${m.name} (${m.version}) is ${(m.archived) ? chalk.yellow('archived') : 'unarchived'} at ${m.address}`));
}
}

async function selectAction() {
Expand Down Expand Up @@ -564,7 +572,7 @@ async function listModuleOptions() {

// Modules a actions
async function addModule() {
let options = ['Permission Manager', 'Transfer Manager', 'Security Token Offering', 'Dividends', 'Burn'];
let options = ['Permission Manager', 'Transfer Manager', 'Security Token Offering', 'Dividends', 'Burn', 'Wallet'];
let index = readlineSync.keyInSelect(options, 'What type of module would you like to add?', { cancel: 'Return' });
switch (options[index]) {
case 'Permission Manager':
Expand All @@ -591,6 +599,12 @@ async function addModule() {
This option is not yet available.
*********************************`));
break;
case 'Wallet':
console.log(chalk.red(`
*********************************
This option is not yet available.
*********************************`));
break;
}
}

Expand Down Expand Up @@ -699,7 +713,7 @@ async function showUserInfo(_user) {
async function getAllModules() {
let allModules = [];
// Iterate over all module types
for (let type = 1; type <= 5; type++) {
for (let type = 1; type <= 8; type++) {
let modules = await common.getAllModulesByType(securityToken, type);
modules.forEach(m => allModules.push(m));
}
Expand Down
58 changes: 31 additions & 27 deletions CLI/commands/transfer_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const input = require('./IO/input');
const output = require('./IO/output');
const { table } = require('table');

///////////////////
// Constants
const WHITELIST_DATA_CSV = `${__dirname}/../data/Transfer/GTM/whitelist_data.csv`;
const FLAG_DATA_CSV = `${__dirname}/../data/Transfer/GTM/flag_data.csv`;
Expand Down Expand Up @@ -133,18 +132,18 @@ async function executeApp() {
async function verifyTransfer(askAmount, askTo) {
let verifyTotalSupply = web3.utils.fromWei(await securityToken.methods.totalSupply().call());
await logTotalInvestors();

let verifyTransferFrom = input.readAddress(`Enter the sender account (${Issuer.address}): `, Issuer.address);
await logBalance(verifyTransferFrom, verifyTotalSupply);

let verifyTransferTo = gbl.constants.ADDRESS_ZERO;
if (askTo) {
verifyTransferTo = input.readAddress('Enter the receiver account: ');
await logBalance(verifyTransferTo, verifyTotalSupply);
}

let verifyTransferAmount = askAmount ? input.readNumberGreaterThan(0, 'Enter amount of tokens to verify: ') : '0';

let verifyResult = await currentTransferManager.methods.verifyTransfer(verifyTransferFrom, verifyTransferTo, web3.utils.toWei(verifyTransferAmount), web3.utils.fromAscii("")).call();
switch (verifyResult[0]) {
case gbl.constants.TRASFER_RESULT.INVALID:
Expand Down Expand Up @@ -470,6 +469,7 @@ async function generalTransferManager() {
break;
case 'Verify transfer':
await verifyTransfer(false, true);
break;
case 'Change the default times used when they are zero':
let fromTimeDefault = readlineSync.questionInt(`Enter the default time (Unix Epoch time) used when fromTime is zero: `);
let toTimeDefault = readlineSync.questionInt(`Enter the default time (Unix Epoch time) used when toTime is zero: `);
Expand Down Expand Up @@ -593,11 +593,10 @@ async function showAllInvestorFlags() {
}
flagDataTable.push([
investorsArray[i],
flagNumbers,
flagNumbers
]);
}
console.log(table(flagDataTable));

}

async function transferRequirements() {
Expand Down Expand Up @@ -684,7 +683,7 @@ async function transferRequirements() {
await transferRequirements();
}

async function modifyTransferRequirements(transferType){
async function modifyTransferRequirements(transferType) {
let fromValidKYC = readlineSync.keyInYNStrict('Should the sender require valid KYC?');
let toValidKYC = readlineSync.keyInYNStrict('Should the recipient require valid KYC?');
let fromRestricted = readlineSync.keyInYNStrict('Should the sender be restricted by a can transfer date?');
Expand All @@ -694,7 +693,7 @@ async function modifyTransferRequirements(transferType){
console.log(chalk.green(" Transfer Requirements sucessfully modified"));
}

async function modifyAllTransferRequirements(transferType, fromValidKYC, toValidKYC, fromRestricted, toRestricted){
async function modifyAllTransferRequirements(transferType, fromValidKYC, toValidKYC, fromRestricted, toRestricted) {
let modifyAllTransferRequirementsAction = currentTransferManager.methods.modifyTransferRequirementsMulti(transferType, fromValidKYC, toValidKYC, fromRestricted, toRestricted);
let receipt = await common.sendTransaction(modifyAllTransferRequirementsAction);
console.log(chalk.green(" Transfer Requirements sucessfully modified"));
Expand All @@ -706,20 +705,25 @@ function showWhitelistTable(investorsArray, canSendAfterArray, canReceiveAfterAr
let canReceiveAfter;
let expiryTime;
for (let i = 0; i < investorsArray.length; i++) {
if (canSendAfterArray[i] == 0) {
canSendAfter = chalk.yellow.bold(" DEFAULT");
} else {
canSendAfter = canSendAfterArray[i] >= Date.now() / 1000
? chalk.red.bold(moment.unix(canSendAfterArray[i]).format('MM/DD/YYYY HH:mm'))
: moment.unix(canSendAfterArray[i]).format('MM/DD/YYYY HH:mm');
}

if (canSendAfterArray[i] == 0) canSendAfter = chalk.yellow.bold(" DEFAULT");
else canSendAfter = canSendAfterArray[i] >= Date.now() / 1000 ?
chalk.red.bold(moment.unix(canSendAfterArray[i]).format('MM/DD/YYYY HH:mm')) :
moment.unix(canSendAfterArray[i]).format('MM/DD/YYYY HH:mm');

if (canReceiveAfterArray[i] == 0) canReceiveAfter = chalk.yellow.bold(" DEFAULT");
else canReceiveAfter = (canReceiveAfterArray[i] >= Date.now() / 1000) ?
chalk.red.bold(moment.unix(canReceiveAfterArray[i]).format('MM/DD/YYYY HH:mm')) :
moment.unix(canReceiveAfterArray[i]).format('MM/DD/YYYY HH:mm');
if (canReceiveAfterArray[i] == 0) {
canReceiveAfter = chalk.yellow.bold(" DEFAULT");
} else {
canReceiveAfter = (canReceiveAfterArray[i] >= Date.now() / 1000)
? chalk.red.bold(moment.unix(canReceiveAfterArray[i]).format('MM/DD/YYYY HH:mm'))
: moment.unix(canReceiveAfterArray[i]).format('MM/DD/YYYY HH:mm');
}

expiryTime = (expiryTimeArray[i] <= Date.now() / 1000 ?
chalk.red.bold(moment.unix(expiryTimeArray[i]).format('MM/DD/YYYY HH:mm')) :
moment.unix(expiryTimeArray[i]).format('MM/DD/YYYY HH:mm'));
expiryTime = (expiryTimeArray[i] <= Date.now() / 1000
? chalk.red.bold(moment.unix(expiryTimeArray[i]).format('MM/DD/YYYY HH:mm'))
: moment.unix(expiryTimeArray[i]).format('MM/DD/YYYY HH:mm'));

dataTable.push([
investorsArray[i],
Expand Down Expand Up @@ -1008,7 +1012,7 @@ async function matmManageRevoke(selectedApproval) {
async function getApprovalsArray() {
let address = input.readAddress('Enter an address to filter or leave empty to get all the approvals: ', gbl.constants.ADDRESS_ZERO);
if (address == gbl.constants.ADDRESS_ZERO) {
return await getApprovals();
return getApprovals();
} else {
let approvals = await getApprovalsToAnAddress(address);
if (!approvals.length) {
Expand Down Expand Up @@ -1081,7 +1085,6 @@ async function matmGenericCsv(path, f) {
}

async function addManualApproveInBatch() {

var f = (row) => {
return (web3.utils.isAddress(row[0]) &&
web3.utils.isAddress(row[1]) &&
Expand All @@ -1106,7 +1109,6 @@ async function addManualApproveInBatch() {
}

async function revokeManualApproveInBatch() {

var f = (row) => {
return (web3.utils.isAddress(row[0]) &&
web3.utils.isAddress(row[1]))
Expand All @@ -1125,7 +1127,6 @@ async function revokeManualApproveInBatch() {
}

async function modifyManualApproveInBatch() {

var f = (row) => {
return (web3.utils.isAddress(row[0]) &&
web3.utils.isAddress(row[1]) &&
Expand Down Expand Up @@ -1207,6 +1208,7 @@ async function percentageTransferManager() {
switch (optionSelected) {
case 'Verify transfer':
await verifyTransfer(false, true);
break;
case 'Change max holder percentage':
let maxHolderPercentage = toWeiPercentage(input.readPercentage('Enter the maximum amount of tokens in percentage that an investor can hold'));
let changeHolderPercentageAction = currentTransferManager.methods.changeHolderPercentage(maxHolderPercentage);
Expand Down Expand Up @@ -1292,6 +1294,7 @@ async function blacklistTransferManager() {
switch (optionSelected) {
case 'Verify transfer':
await verifyTransfer(false, false);
break;
case 'Add new blacklist':
let name = input.readStringNonEmpty(`Enter the name of the blacklist type: `);
let minuteFromNow = Math.floor(Date.now() / 1000) + 60;
Expand Down Expand Up @@ -1718,7 +1721,7 @@ async function volumeRestrictionTM() {
addressesAndRestrictions.typeOfRestriction,
addressesAndRestrictions.rollingPeriodInDays,
addressesAndRestrictions.startTime,
addressesAndRestrictions.endTime,
addressesAndRestrictions.endTime
);
break;
case 'Show exempted addresses':
Expand Down Expand Up @@ -2680,9 +2683,10 @@ async function initialize(_tokenSymbol) {
welcome();
await setup();
securityToken = await common.selectToken(securityTokenRegistry, _tokenSymbol);
tokenSymbol = await securityToken.methods.symbol().call();
if (securityToken === null) {
process.exit(0);
} else {
tokenSymbol = await securityToken.methods.symbol().call();
}
}

Expand Down
Loading