cc-zos-vouching
Version:
Vouching logic for the EVM packages of the ZeppelinOS smart contract platform
209 lines (153 loc) • 12.2 kB
JavaScript
;
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;
}