Skip to content
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
226 changes: 122 additions & 104 deletions CLI/commands/strMigrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var global = require('./common/global');

let network;

async function executeApp(toStrAddress, fromTrAddress, fromStrAddress, remoteNetwork) {
async function executeApp(toStrAddress, fromTrAddress, fromStrAddress, singleTicker, remoteNetwork) {
network = remoteNetwork;
await global.initialize(remoteNetwork);

Expand All @@ -22,10 +22,10 @@ async function executeApp(toStrAddress, fromTrAddress, fromStrAddress, remoteNet
try {
let toSecurityTokenRegistry = await step_instance_toSTR(toStrAddress);
let fromTickerRegistry = await step_instance_fromTR(fromTrAddress);
let tickers = await step_get_registered_tickers(fromTickerRegistry);
let tickers = await step_get_registered_tickers(fromTickerRegistry, singleTicker);
await step_register_tickers(tickers, toSecurityTokenRegistry);
let fromSecurityTokenRegistry = await step_instance_fromSTR(fromStrAddress);
let tokens = await step_get_deployed_tokens(fromSecurityTokenRegistry);
let tokens = await step_get_deployed_tokens(fromSecurityTokenRegistry, singleTicker);
await step_launch_STs(tokens, toSecurityTokenRegistry);
} catch (err) {
console.log(err);
Expand Down Expand Up @@ -85,41 +85,43 @@ async function step_instance_fromTR(fromTrAddress){
return fromTR;
}

async function step_get_registered_tickers(tickerRegistry) {
async function step_get_registered_tickers(tickerRegistry, singleTicker) {
let tickers = [];
let expiryTime = await tickerRegistry.methods.expiryLimit().call();

let events = await tickerRegistry.getPastEvents('LogRegisterTicker', { fromBlock: 0});
if (events.length == 0) {
let logs = await getLogsFromEtherscan(tickerRegistry.options.address, 0, 'latest', 'LogRegisterTicker(address,string,string,bytes32,uint256)');
if (logs.length == 0) {
console.log("No ticker registration events were emitted.");
} else {
for (let event of events) {
//for (let index = 0; index < 2; index++) {
//const event = events[index];
let details = await tickerRegistry.methods.getDetails(event.returnValues._symbol).call();
let _symbol = event.returnValues._symbol;
let _owner = details[0];
let _name = details[2];
let _registrationDate = details[1];
let _status = details[4];

console.log(`------------ Ticker Registered ------------`);
console.log(`Ticker: ${_symbol}`);
console.log(`Owner: ${_owner}`);
console.log(`Token name: ${_name}`);
console.log(`Timestamp: ${_registrationDate}`);
console.log(`Transaction hash: ${event.transactionHash}`);
console.log(`-------------------------------------------`);
console.log(`\n`);

tickers.push({
ticker: _symbol,
owner: _owner,
name: _name,
registrationDate: new web3.utils.BN(_registrationDate),
expiryDate: new web3.utils.BN(_registrationDate).add(new web3.utils.BN(expiryTime)),
status: _status
});
for (let log of logs) {
let event = common.getEventFromLogs(tickerRegistry._jsonInterface, [log], 'LogRegisterTicker');
if (typeof singleTicker !== undefined && event._symbol == singleTicker) {
let details = await tickerRegistry.methods.getDetails(event._symbol).call();
let expiredTicker = details[0] == '0x0000000000000000000000000000000000000000';
let _symbol = event._symbol;
let _owner = expiredTicker ? event._owner : details[0];
let _name = expiredTicker ? event._name : details[2];
let _registrationDate = expiredTicker ? event._timestamp : details[1];
let _status = details[4];

console.log(`------------ Ticker Registered ------------`);
console.log(`Ticker: ${_symbol}`);
console.log(`Owner: ${_owner}`);
console.log(`Token name: ${_name}`);
console.log(`Timestamp: ${_registrationDate}`);
console.log(`Transaction hash: ${log.transactionHash}`);
console.log(`-------------------------------------------`);
console.log(`\n`);

tickers.push({
ticker: _symbol,
owner: _owner,
name: _name,
registrationDate: new web3.utils.BN(_registrationDate),
expiryDate: new web3.utils.BN(_registrationDate).add(new web3.utils.BN(expiryTime)),
status: _status
});
}
}
}

Expand All @@ -128,11 +130,6 @@ async function step_get_registered_tickers(tickerRegistry) {
}

async function step_register_tickers(tickers, securityTokenRegistry) {
if (readlineSync.keyInYNStrict(`Do you want to migrate a single Ticker?`)) {
let tickerToMigrate = readlineSync.question(`Enter the ticker to migrate: `);
tickers = tickers.filter(t => t.ticker == tickerToMigrate);
}

if (tickers.length == 0) {
console.log(chalk.yellow(`There are no tickers to migrate!`));
} else if (readlineSync.keyInYNStrict(`Do you want to migrate ${tickers.length} Tickers?`)) {
Expand Down Expand Up @@ -187,63 +184,69 @@ async function step_instance_fromSTR(fromStrAddress){
return fromSTR;
}

async function step_get_deployed_tokens(securityTokenRegistry) {
async function step_get_deployed_tokens(securityTokenRegistry, singleTicker) {
let tokens = [];

let events = await securityTokenRegistry.getPastEvents('LogNewSecurityToken', { fromBlock: 0});
if (events.length == 0) {
//let events = await securityTokenRegistry.getPastEvents('LogNewSecurityToken', { fromBlock: 0});
let logs = await getLogsFromEtherscan(securityTokenRegistry.options.address, 0, 'latest', 'LogNewSecurityToken(string,address,address)');
if (logs.length == 0) {
console.log("No security token events were emitted.");
} else {
for (let event of events) {
//for (let index = 0; index < 2; index++) {
//const event = events[index];
let tokenAddress = event.returnValues._securityTokenAddress;
let securityTokenABI = JSON.parse(require('fs').readFileSync('./CLI/data/SecurityToken1-4-0.json').toString()).abi;
console.log(`Creating SecurityToken contract instance of address: ${tokenAddress}...`);
let token = new web3.eth.Contract(securityTokenABI, tokenAddress);
token.setProvider(web3.currentProvider);

let tokenName = await token.methods.name().call();
let tokenSymbol = await token.methods.symbol().call();
let tokenOwner = await token.methods.owner().call();
let tokenDetails = await token.methods.tokenDetails().call();
let tokenDivisible = await token.methods.granularity().call() == 1;
let tokenDeployedAt = (await web3.eth.getBlock(event.blockNumber)).timestamp;

let gmtAddress = (await token.methods.getModule(2, 0).call())[1];
let gtmABI = JSON.parse(require('fs').readFileSync('./CLI/data/GeneralTransferManager1-4-0.json').toString()).abi;
let gmt = new web3.eth.Contract(gtmABI, gmtAddress);
let gtmEvents = await gmt.getPastEvents('LogModifyWhitelist', { fromBlock: event.blockNumber});

let mintedEvents = [];
if (gtmEvents.length > 0) {
mintedEvents = await token.getPastEvents('Minted', { fromBlock: event.blockNumber});
}

console.log(`--------- SecurityToken launched ---------`);
console.log(`Token address: ${event.returnValues._securityTokenAddress}`);
console.log(`Symbol: ${tokenSymbol}`);
console.log(`Name: ${tokenName}`);
console.log(`Owner: ${tokenOwner}`);
console.log(`Details: ${tokenDetails}`);
console.log(`Divisble: ${tokenDivisible}`);
console.log(`Deployed at: ${tokenDeployedAt}`);
console.log(`Transaction hash: ${event.transactionHash}`);
console.log(`------------------------------------------`);
console.log(``);

for (let log of logs) {
let event = common.getEventFromLogs(securityTokenRegistry._jsonInterface, [log], 'LogNewSecurityToken');
if (typeof singleTicker !== undefined && event._ticker == singleTicker) {
let tokenAddress = event._securityTokenAddress;
let securityTokenABI = JSON.parse(require('fs').readFileSync('./CLI/data/SecurityToken1-4-0.json').toString()).abi;
console.log(`Creating SecurityToken contract instance of address: ${tokenAddress}...`);
let token = new web3.eth.Contract(securityTokenABI, tokenAddress);
token.setProvider(web3.currentProvider);

let tokenName = await token.methods.name().call();
let tokenSymbol = await token.methods.symbol().call();
let tokenOwner = await token.methods.owner().call();
let tokenDetails = await token.methods.tokenDetails().call();
let tokenDivisible = await token.methods.granularity().call() == 1;
let tokenDeployedAt = (await web3.eth.getBlock(web3.utils.hexToNumber(log.blockNumber))).timestamp;

let gmtAddress = (await token.methods.getModule(2, 0).call())[1];
let gtmABI = JSON.parse(require('fs').readFileSync('./CLI/data/GeneralTransferManager1-4-0.json').toString()).abi;
let gmt = new web3.eth.Contract(gtmABI, gmtAddress);
//let gtmEvents = await gmt.getPastEvents('LogModifyWhitelist', { fromBlock: event.blockNumber});
let gtmLogs = await getLogsFromEtherscan(gmt.options.address, 0, 'latest', 'LogModifyWhitelist(address,uint256,address,uint256,uint256,uint256,bool)');
let gtmEvents = common.getMultipleEventsFromLogs(gmt._jsonInterface, gtmLogs, 'LogModifyWhitelist');

let mintedEvents = [];
if (gtmEvents.length > 0) {
//mintedEvents = await token.getPastEvents('Minted', { fromBlock: event.blockNumber});
let mintedLogs = await getLogsFromEtherscan(token.options.address, 0, 'latest', 'Minted(address,uint256)');
mintedEvents = common.getMultipleEventsFromLogs(token._jsonInterface, mintedLogs, 'Minted');
}

tokens.push({
name: tokenName,
ticker: tokenSymbol,
owner: tokenOwner,
details: tokenDetails,
address: tokenAddress,
deployedAt: tokenDeployedAt,
divisble: tokenDivisible,
gmtEvents: gtmEvents,
mintedEvents: mintedEvents
});
console.log(`--------- SecurityToken launched ---------`);
console.log(`Token address: ${event._securityTokenAddress}`);
console.log(`Symbol: ${tokenSymbol}`);
console.log(`Name: ${tokenName}`);
console.log(`Owner: ${tokenOwner}`);
console.log(`Details: ${tokenDetails}`);
console.log(`Divisble: ${tokenDivisible}`);
console.log(`Deployed at: ${tokenDeployedAt}`);
console.log(`Transaction hash: ${log.transactionHash}`);
console.log(`------------------------------------------`);
console.log(``);


tokens.push({
name: tokenName,
ticker: tokenSymbol,
owner: tokenOwner,
details: tokenDetails,
address: tokenAddress,
deployedAt: tokenDeployedAt,
divisble: tokenDivisible,
gmtEvents: gtmEvents,
mintedEvents: mintedEvents
});
}
}
}

Expand All @@ -252,12 +255,7 @@ async function step_get_deployed_tokens(securityTokenRegistry) {
}

async function step_launch_STs(tokens, securityTokenRegistry) {
if (readlineSync.keyInYNStrict(`Do you want to migrate a single Security Token?`)) {
let tokenToMigrate = readlineSync.question(`Enter the Security Token symbol to migrate: `);
tokens = tokens.filter(t => t.ticker == tokenToMigrate);
}

if (tickers.length == 0) {
if (tokens.length == 0) {
console.log(chalk.yellow(`There are no security tokens to migrate!`));
} else if (readlineSync.keyInYNStrict(`Do you want to migrate ${tokens.length} Security Tokens?`)) {
let i = 0;
Expand Down Expand Up @@ -292,18 +290,18 @@ async function step_launch_STs(tokens, securityTokenRegistry) {
// Whitelisting investors
for (const gmtEvent of t.gmtEvents) {
let modifyWhitelistAction = gmt.methods.modifyWhitelist(
gmtEvent.returnValues._investor,
new web3.utils.BN(gmtEvent.returnValues._fromTime),
new web3.utils.BN(gmtEvent.returnValues._toTime),
new web3.utils.BN(gmtEvent.returnValues._expiryTime),
gmtEvent.returnValues._canBuyFromSTO
gmtEvent._investor,
new web3.utils.BN(gmtEvent._fromTime),
new web3.utils.BN(gmtEvent._toTime),
new web3.utils.BN(gmtEvent._expiryTime),
gmtEvent._canBuyFromSTO
);
let modifyWhitelistReceipt = await common.sendTransaction(Issuer, modifyWhitelistAction, defaultGasPrice);
totalGas = totalGas.add(new web3.utils.BN(modifyWhitelistReceipt.gasUsed));
}
// Minting tokens
for (const mintedEvent of t.mintedEvents) {
let mintAction = newToken.methods.mint(mintedEvent.returnValues.to, new web3.utils.BN(mintedEvent.returnValues.value));
let mintAction = newToken.methods.mint(mintedEvent.to, new web3.utils.BN(mintedEvent.value));
let mintReceipt = await common.sendTransaction(Issuer, mintAction, defaultGasPrice);
totalGas = totalGas.add(new web3.utils.BN(mintReceipt.gasUsed));
}
Expand Down Expand Up @@ -359,6 +357,26 @@ ${failed.map(ticker => chalk.red(`${ticker.ticker}`)).join('\n')}
`);
}

async function getLogsFromEtherscan(_address, _fromBlock, _toBlock, _eventSignature) {
let urlDomain = network == 'kovan' ? 'api-kovan' : 'api';
const options = {
url: `https://${urlDomain}.etherscan.io/api`,
qs: {
module: 'logs',
action: 'getLogs',
fromBlock: _fromBlock,
toBlock: _toBlock,
address: _address,
topic0: web3.utils.sha3(_eventSignature),
apikey: 'THM9IUVC2DJJ6J5MTICDE6H1HGQK14X559'
},
method: 'GET',
json: true
};
let data = await request(options);
return data.result;
}

async function getABIfromEtherscan(_address) {
let urlDomain = network == 'kovan' ? 'api-kovan' : 'api';
const options = {
Expand All @@ -377,7 +395,7 @@ async function getABIfromEtherscan(_address) {
}

module.exports = {
executeApp: async function(toStrAddress, fromTrAddress, fromStrAddress, remoteNetwork) {
return executeApp(toStrAddress, fromTrAddress, fromStrAddress, remoteNetwork);
executeApp: async function(toStrAddress, fromTrAddress, fromStrAddress, singleTicker, remoteNetwork) {
return executeApp(toStrAddress, fromTrAddress, fromStrAddress, singleTicker, remoteNetwork);
}
};
5 changes: 3 additions & 2 deletions CLI/polymath-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,11 @@ program

program
.command('strMigrator [toStrAddress] [fromTrAddress] [fromStrAddress]')
.option('-tick, --singleTicker <ticker>', 'It only reads and migrates the ticker and token for given token symbol')
.alias('str')
.description('Runs STR Migrator')
.action(async function(toStrAddress, fromTrAddress, fromStrAddress) {
await strMigrator.executeApp(toStrAddress, fromTrAddress, fromStrAddress, program.remoteNode);
.action(async function(toStrAddress, fromTrAddress, fromStrAddress, cmd) {
await strMigrator.executeApp(toStrAddress, fromTrAddress, fromStrAddress, cmd.singleTicker, program.remoteNode);
});

program
Expand Down
Loading