diff --git a/CLI/commands/strMigrator.js b/CLI/commands/strMigrator.js index 545455f46..d113c586b 100644 --- a/CLI/commands/strMigrator.js +++ b/CLI/commands/strMigrator.js @@ -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); @@ -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); @@ -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 + }); + } } } @@ -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?`)) { @@ -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 + }); + } } } @@ -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; @@ -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)); } @@ -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 = { @@ -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); } }; \ No newline at end of file diff --git a/CLI/polymath-cli.js b/CLI/polymath-cli.js index 49f578df0..d9e7b9fd4 100644 --- a/CLI/polymath-cli.js +++ b/CLI/polymath-cli.js @@ -137,10 +137,11 @@ program program .command('strMigrator [toStrAddress] [fromTrAddress] [fromStrAddress]') + .option('-tick, --singleTicker ', '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 diff --git a/scripts/tokenInfo.js b/scripts/tokenInfo.js index 2df8c57c4..7989b105e 100644 --- a/scripts/tokenInfo.js +++ b/scripts/tokenInfo.js @@ -1,19 +1,18 @@ const Web3 = require("web3"); -const fs = require("fs"); -const async = require("async"); -const path = require("path"); const web3 = new Web3(new Web3.providers.HttpProvider("https://mainnet.infura.io/")); +var request = require('request-promise') -const securityTokenRegistryABI = JSON.parse(require('fs').readFileSync('../build/contracts/SecurityTokenRegistry.json').toString()).abi; -const securityTokenABI = JSON.parse(require('fs').readFileSync('../build/contracts/SecurityToken.json').toString()).abi; -const generalTransferManagerABI = JSON.parse(require('fs').readFileSync('../build/contracts/GeneralTransferManager.json').toString()).abi; -const securityTokenRegistryAddress = "0xEf58491224958d978fACF55D2120c55A24516B98"; -const securityTokenRegistry = new web3.eth.Contract(securityTokenRegistryABI, securityTokenRegistryAddress); +const securityTokenABI = JSON.parse(require('fs').readFileSync('../CLI/data/SecurityToken1-4-0.json').toString()).abi; +const generalTransferManagerABI = JSON.parse(require('fs').readFileSync('../CLI/data/GeneralTransferManager1-4-0.json').toString()).abi; async function getTokens() { - let strEvents = await web3.eth.getPastLogs({fromBlock:'0x5C5C18', address:securityTokenRegistry.address, topics: ["0x2510d802a0818e71139a7680a6388bcffcd3fa686e02a0f7319488c5bdb38fcb"]}); - for (let i = 0; i < strEvents.length; i++) { - let tokenAddress = '0x' + strEvents[i].topics[1].slice(26,66) + const securityTokenRegistryAddress = "0xEf58491224958d978fACF55D2120c55A24516B98"; + const securityTokenRegistryABI = await getABIfromEtherscan(securityTokenRegistryAddress); + const securityTokenRegistry = new web3.eth.Contract(securityTokenRegistryABI, securityTokenRegistryAddress); + + let logs = await getLogsFromEtherscan(securityTokenRegistry.options.address, web3.utils.hexToNumber('0x5C5C18'), 'latest', 'LogNewSecurityToken(string,address,address)'); + for (let i = 0; i < logs.length; i++) { + let tokenAddress = '0x' + logs[i].topics[1].slice(26,66) await getInfo(tokenAddress); } } @@ -32,7 +31,7 @@ async function getInfo(tokenAddress) { console.log("Finished Issuer Minting: " + await token.methods.finishedIssuerMinting().call()); console.log("Finished STO Minting: " + await token.methods.finishedSTOMinting().call()); let gtmRes = await token.methods.modules(2, 0).call(); - let gtmEvents = await web3.eth.getPastLogs({fromBlock:'0x5C5C18', address:gtmRes.moduleAddress}); + let gtmEvents = await getLogsFromEtherscan(gtmRes.moduleAddress, web3.utils.hexToNumber('0x5C5C18'), 'latest', 'LogModifyWhitelist(address,uint256,address,uint256,uint256,uint256,bool)'); console.log("Count of GeneralTransferManager Events: " + gtmEvents.length); console.log("Modules Attached (TransferManager):"); await getModules(2, token); @@ -65,4 +64,41 @@ async function getModules(type, token) { } } -getTokens(); +async function getLogsFromEtherscan(_address, _fromBlock, _toBlock, _eventSignature) { + let urlDomain = '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 = 'api'; + const options = { + url: `https://${urlDomain}.etherscan.io/api`, + qs: { + module: 'contract', + action: 'getabi', + address: _address, + apikey: 'THM9IUVC2DJJ6J5MTICDE6H1HGQK14X559' + }, + method: 'GET', + json: true + }; + let data = await request(options); + return JSON.parse(data.result); +} + +getTokens(); \ No newline at end of file diff --git a/scripts/tokenInfo2.js b/scripts/tokenInfo2.js new file mode 100644 index 000000000..236fa9773 --- /dev/null +++ b/scripts/tokenInfo2.js @@ -0,0 +1,107 @@ +const Web3 = require("web3"); +const web3 = new Web3(new Web3.providers.HttpProvider("https://kovan.infura.io/")); +var request = require('request-promise') + +const securityTokenABI = JSON.parse(require('fs').readFileSync('../build/contracts/SecurityToken.json').toString()).abi; +const generalTransferManagerABI = JSON.parse(require('fs').readFileSync('../build/contracts/GeneralTransferManager.json').toString()).abi; + +async function getTokens() { + const securityTokenRegistryAddress = "0x91110c2f67e2881a8540417be9eadf5bc9f2f248"; + const securityTokenRegistryABI = await getABIfromEtherscan(securityTokenRegistryAddress); + const securityTokenRegistry = new web3.eth.Contract(securityTokenRegistryABI, securityTokenRegistryAddress); + + let logs = await getLogsFromEtherscan(securityTokenRegistry.options.address, 9299699, 'latest', 'NewSecurityToken(string,string,address,address,uint256,address,bool,uint256)'); + for (let i = 0; i < logs.length; i++) { + let tokenAddress = '0x' + logs[i].topics[1].slice(26,66) + await getInfo(tokenAddress); + } +} + +async function getInfo(tokenAddress) { + let token = new web3.eth.Contract(securityTokenABI, tokenAddress); + console.log("Token - " + tokenAddress); + console.log("----------------------"); + console.log("Owner: " + await token.methods.owner().call()); + console.log("Name: " + await token.methods.name().call()); + console.log("Details: " + await token.methods.tokenDetails().call()); + console.log("Symbol: " + await token.methods.symbol().call()); + console.log("Granularity: " + await token.methods.granularity().call()); + console.log("Total Supply: " + await token.methods.totalSupply().call()); + console.log("Transfers Frozen: " + await token.methods.transfersFrozen().call()); + console.log("Minting Frozen: " + await token.methods.mintingFrozen().call()); + let controllerDisabled = await token.methods.controllerDisabled().call(); + if (controllerDisabled) { + console.log("Controller disabled: YES"); + } else { + console.log("Controller: " + await token.methods.controller().call()); + } + console.log("Investors: " + await token.methods.getInvestorCount().call()); + console.log("Latest Checkpoint: " + await token.methods.currentCheckpointId().call()); + let gtmEventsCount = 0; + let gtmModules = await token.methods.getModulesByName(web3.utils.toHex('GeneralTransferManager')).call(); + for (const m of gtmModules) { + let gtmEvents = await getLogsFromEtherscan(m, 9299699, 'latest', 'ModifyWhitelist(address,uint256,address,uint256,uint256,uint256,bool)'); + gtmEventsCount += gtmEvents.length; + } + console.log("Count of GeneralTransferManager Events: " + gtmEventsCount); + console.log("Modules Attached (TransferManager):"); + await getModules(2, token); + console.log("Modules Attached (PermissionManager):"); + await getModules(1, token); + console.log("Modules Attached (STO):"); + await getModules(3, token); + console.log("Modules Attached (Checkpoint):"); + await getModules(4, token); + console.log("Modules Attached (Burn):"); + await getModules(5, token); + console.log(); + console.log(); +} + +async function getModules(type, token) { + let modules = await token.methods.getModulesByType(type).call(); + for (const m of modules) { + let moduleData = await token.methods.getModule(m).call(); + console.log(" Name: " + web3.utils.toAscii(moduleData[0])); + console.log(" Address: " + m); + } +} + +async function getLogsFromEtherscan(_address, _fromBlock, _toBlock, _eventSignature) { + let urlDomain = 'api-kovan'; + 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 = 'api-kovan'; + const options = { + url: `https://${urlDomain}.etherscan.io/api`, + qs: { + module: 'contract', + action: 'getabi', + address: _address, + apikey: 'THM9IUVC2DJJ6J5MTICDE6H1HGQK14X559' + }, + method: 'GET', + json: true + }; + let data = await request(options); + return JSON.parse(data.result); +} + +getTokens(); \ No newline at end of file