UNPKG

cc-zos-vouching

Version:

Vouching logic for the EVM packages of the ZeppelinOS smart contract platform

209 lines (153 loc) 12.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyAppSetup = verifyAppSetup; exports.verifyJurisdiction = verifyJurisdiction; exports.verifyZEPToken = verifyZEPToken; exports.verifyVouching = verifyVouching; exports.verifyOrganizationsValidator = verifyOrganizationsValidator; exports.verifyTPLConfiguration = verifyTPLConfiguration; var _log = require('../helpers/log'); var _log2 = _interopRequireDefault(_log); var _zos = require('zos'); var _ccZosLib = require('cc-zos-lib'); var _fetchKernelContracts = require('../kernel/fetchKernelContracts'); var _validateAddress = require('../helpers/validateAddress'); var _validateAddress2 = _interopRequireDefault(_validateAddress); var _constants = require('../constants'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const { ZosPackageFile } = _zos.files; exports.default = async function verify({ network, txParams }) { _log2.default.info(`Verifying vouching app on network ${network}...`); const networkFile = new ZosPackageFile().networkFile(network); const successfulApp = await verifyAppSetup(networkFile); const successfulJurisdiction = successfulApp && (await verifyJurisdiction(networkFile, txParams)); const successfulZepToken = successfulJurisdiction && (await verifyZEPToken(networkFile, txParams)); const successfulVouching = successfulZepToken && (await verifyVouching(networkFile, txParams)); const successfulValidator = successfulVouching && (await verifyOrganizationsValidator(networkFile, txParams)); const successfulConfiguration = successfulValidator && (await verifyTPLConfiguration(networkFile, txParams)); if (successfulConfiguration) _log2.default.info('\n\nVouching app was deployed and configured successfully!');else _log2.default.error('\n\nCould not complete verification process since there are required previous steps not completed.'); }; async function verifyAppSetup(networkFile) { _log2.default.base('\n--------------------------------------------------------------------\n'); _log2.default.base('Verifying ZeppelinOS app...'); if (_ccZosLib.FileSystem.exists(networkFile.fileName)) { const validAppAddress = (0, _validateAddress2.default)(networkFile.appAddress); const validPackageAddress = (0, _validateAddress2.default)(networkFile.packageAddress); const validVersion = networkFile.version && networkFile.version !== ''; validAppAddress ? _log2.default.info(' ✔ App address is valid') : _log2.default.error(` ✘ App address ${networkFile.appAddress} is not valid`); validPackageAddress ? _log2.default.info(' ✔ Package address is valid') : _log2.default.error(` ✘ Package address ${networkFile.packageAddress} is not valid`); validVersion ? _log2.default.info(' ✔ Version name is valid') : _log2.default.error(` ✘ Version name "${networkFile.version}" is not valid`); if (validAppAddress && validPackageAddress && validVersion) { const App = _ccZosLib.Contracts.getFromNodeModules('zos-lib', 'App'); const app = App.at(networkFile.appAddress); const [packageAddress, version] = await app.getPackage('zos-vouching'); const registeredPackage = packageAddress === networkFile.packageAddress; const registeredVersion = _ccZosLib.Semver.semanticVersionEqual(version, networkFile.version); registeredPackage ? _log2.default.info(' ✔ Package address is registered on the app') : _log2.default.error(` ✘ Package address ${networkFile.packageAddress} is not registered on the app ${networkFile.appAddress}`); registeredVersion ? _log2.default.info(' ✔ Requested version is registered on-chain') : _log2.default.error(` ✘ Requested version ${networkFile.version} is not registered on-chain, it was expected ${version}`); return registeredPackage && registeredVersion; } else return false; } else { _log2.default.error(` ✘ Cannot find ZeppelinOS ${networkFile.network} file.`); return false; } } async function verifyJurisdiction(networkFile, txParams) { _log2.default.base('\n--------------------------------------------------------------------\n'); _log2.default.base('Verifying basic jurisdiction...'); const jurisdiction = (0, _fetchKernelContracts.fetchJurisdiction)(networkFile); if (jurisdiction) { const jurisdictionOwner = await jurisdiction.owner(); const ownerMatches = jurisdictionOwner === txParams.from; ownerMatches ? _log2.default.info(' ✔ Jurisdiction owner matches requested owner') : _log2.default.error(` ✘ Jurisdiction owner ${jurisdictionOwner} does not match requested owner, it was expected ${txParams.from}`); return ownerMatches; } else { _log2.default.error(' ✘ Missing valid instance of BasicJurisdiction'); return false; } } async function verifyZEPToken(networkFile, txParams) { _log2.default.base('\n--------------------------------------------------------------------\n'); _log2.default.base('Verifying ZEP Token...'); const zepToken = (0, _fetchKernelContracts.fetchZepToken)(networkFile); if (zepToken) { const name = await zepToken.name(); const symbol = await zepToken.symbol(); const decimals = await zepToken.decimals(); const totalSupply = await zepToken.totalSupply(); const isPauser = await zepToken.isPauser(txParams.from); const nameMatches = name === _constants.ZEPTOKEN_NAME; const symbolMatches = symbol === _constants.ZEPTOKEN_SYMBOL; const decimalsMatches = decimals.eq(_constants.ZEPTOKEN_DECIMALS); const totalSupplyMatches = totalSupply.eq(new web3.BigNumber(`${_constants.ZEPTOKEN_SUPPLY}e${decimals}`)); isPauser ? _log2.default.info(' ✔ ZEP Token deployer has pauser role') : _log2.default.error(` ✘ ZEP Token deployer ${txParams.from} does not have pauser role`); nameMatches ? _log2.default.info(' ✔ ZEP Token name matches requested value') : _log2.default.error(` ✘ ZEP Token name "${name}" does not match expected value "${_constants.ZEPTOKEN_NAME}"`); symbolMatches ? _log2.default.info(' ✔ ZEP Token symbol matches requested value') : _log2.default.error(` ✘ ZEP Token symbol "${symbol}" does not match expected value "${_constants.ZEPTOKEN_SYMBOL}"`); decimalsMatches ? _log2.default.info(' ✔ ZEP Token decimals matches the requested value') : _log2.default.error(` ✘ ZEP Token decimals ${decimals} does not match expected value ${_constants.ZEPTOKEN_DECIMALS}`); totalSupplyMatches ? _log2.default.info(' ✔ ZEP Token total supply matches the requested value') : _log2.default.error(` ✘ ZEP Token total supply ${totalSupply} does not match expected value ${_constants.ZEPTOKEN_SUPPLY}`); return isPauser && nameMatches && symbolMatches && decimalsMatches && totalSupplyMatches; } else { _log2.default.error(' ✘ Missing valid instance of ZEP Token'); return false; } } async function verifyVouching(networkFile, txParams) { _log2.default.base('\n--------------------------------------------------------------------\n'); _log2.default.base('Verifying Vouching contract...'); const vouching = (0, _fetchKernelContracts.fetchVouching)(networkFile); if (vouching) { const token = await vouching.token(); const minimumStake = await vouching.minimumStake(); const zepTokenAddress = (0, _fetchKernelContracts.fetchZepToken)(networkFile).address; const tokenMatches = token === zepTokenAddress; const minimumStakeMatches = minimumStake.eq(_constants.VOUCHING_MIN_STAKE); tokenMatches ? _log2.default.info(' ✔ Vouching token matches ZEP Token deployed instance') : _log2.default.error(` ✘ Vouching token ${token} does not match ZEP Token deployed instance ${zepTokenAddress}`); minimumStakeMatches ? _log2.default.info(' ✔ Vouching minimum stake matches requested value') : _log2.default.error(` ✘ Vouching minimum stake ${minimumStake} does not match requested value, it was expected ${_constants.VOUCHING_MIN_STAKE}`); return tokenMatches && minimumStakeMatches; } else { _log2.default.error(' ✘ Missing valid instance of Vouching'); return false; } } async function verifyOrganizationsValidator(networkFile, txParams) { _log2.default.base('\n--------------------------------------------------------------------\n'); _log2.default.base('Verifying Organizations validator...'); const validator = (0, _fetchKernelContracts.fetchValidator)(networkFile); if (validator) { const owner = await validator.owner(); const jurisdiction = await validator.getJurisdiction(); const jurisdictionAddress = (0, _fetchKernelContracts.fetchJurisdiction)(networkFile).address; const ownerMatches = owner === txParams.from; const jurisdictionMatches = jurisdiction === jurisdictionAddress; ownerMatches ? _log2.default.info(' ✔ Organizations validator owner matches requested value') : _log2.default.error(` ✘ Organizations validator owner ${owner} does not match requested value, it was expected ${txParams.from}`); jurisdictionMatches ? _log2.default.info(' ✔ Organizations validator jurisdiction matches BasicJurisdiction deployed instance') : _log2.default.error(` ✘ Organizations validator jurisdiction ${jurisdiction} does not match BasicJurisdiction deployed instance ${jurisdictionAddress}`); return ownerMatches && jurisdictionMatches; } else { _log2.default.error(' ✘ Missing valid instance of OrganizationsValidator'); return false; } } async function verifyTPLConfiguration(networkFile, txParams) { _log2.default.base('\n--------------------------------------------------------------------\n'); _log2.default.base('Verifying TPL configuration...'); const BasicJurisdiction = _ccZosLib.Contracts.getFromNodeModules('tpl-contracts-eth', 'BasicJurisdiction'); const jurisdictionProxies = networkFile._proxiesOf('tpl-contracts-eth/BasicJurisdiction'); const jurisdictionAddress = jurisdictionProxies[jurisdictionProxies.length - 1].address; const jurisdiction = BasicJurisdiction.at(jurisdictionAddress); const OrganizationsValidator = _ccZosLib.Contracts.getFromNodeModules('tpl-contracts-eth', 'OrganizationsValidator'); const validatorProxies = networkFile._proxiesOf('tpl-contracts-eth/OrganizationsValidator'); const validatorAddress = validatorProxies[validatorProxies.length - 1].address; const validator = OrganizationsValidator.at(validatorAddress); const [exists, maximumAccounts, name] = await validator.getOrganizationInformation(txParams.from); const isValidator = await jurisdiction.isValidator(validatorAddress); const canIssueAttributeType = await jurisdiction.canIssueAttributeType(validatorAddress, _constants.ZEPTOKEN_ATTRIBUTE_ID); const organizationMatches = exists && name === _constants.ZEPPELIN_ORG_NAME; const maximumAccountsMatches = maximumAccounts.eq(_constants.ZEPPELIN_ORG_MAX_ADDRESSES); isValidator ? _log2.default.info(' ✔ Organizations validator is correctly set as a validator on the jurisdiction') : _log2.default.error(` ✘ Organizations validator ${validatorAddress} is not set as a validator on the jurisdiction ${jurisdictionAddress}`); canIssueAttributeType ? _log2.default.info(' ✔ Organizations validator is cleared for approval of ZEP Token attribute ID on the jurisdiction') : _log2.default.error(` ✘ Organizations validator ${validatorAddress} is not cleared for approval of ZEP Token attribute ID ${_constants.ZEPTOKEN_ATTRIBUTE_ID} on the jurisdiction ${jurisdictionAddress}`); organizationMatches ? _log2.default.info(' ✔ Zeppelin organization was properly set in the OrganizationsValidator') : _log2.default.error(` ✘ Zeppelin organization "${_constants.ZEPPELIN_ORG_NAME}" is not set in the OrganizationsValidator`); maximumAccountsMatches ? _log2.default.info(' ✔ Zeppelin organization number of maximum accounts was properly set') : _log2.default.error(` ✘ Zeppelin organization number of maximum accounts "${maximumAccounts}" does not match, it was expected ${_constants.ZEPPELIN_ORG_MAX_ADDRESSES}`); return isValidator && canIssueAttributeType && organizationMatches && maximumAccountsMatches; }