Skip to content
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

[3.38]: Add ST storage layout check script in CI pipeline #704

Merged
merged 2 commits into from
Jun 12, 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
16 changes: 16 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,21 @@ jobs:
key: dependency-cache-{{ checksum "package.json" }}
paths:
- node_modules
st-storage-layout-check:
docker:
- image: maxsam4/solidity-kit
steps:
- checkout
- restore_cache:
key: dependency-cache-{{ checksum "package.json" }}
- run: yarn install
- run: node --version
- run: truffle version
- run: npm run st-storage-layout-check
- save_cache:
key: dependency-cache-{{ checksum "package.json" }}
paths:
- node_modules
docs:
docker:
- image: maxsam4/solidity-kit
Expand All @@ -90,6 +105,7 @@ workflows:
jobs:
- coverage
- clash-check
- st-storage-layout-check
daily-builds:
triggers:
- schedule:
Expand Down
15 changes: 12 additions & 3 deletions contracts/tokens/OZStorage.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
pragma solidity ^0.5.0;

/*
* @dev It is the contract that contains the storage items related to the ERC20 contract implementaiton
* of the openzeppelin-solidity. Used to allow the storage declaration of ERC20 to the STGetter contract
*/

contract OZStorage {

mapping (address => uint256) public _balances;
mapping (address => uint256) private _balances;

mapping (address => mapping (address => uint256)) public _allowed;
mapping (address => mapping (address => uint256)) private _allowed;

uint256 public _totalSupply;
uint256 private _totalSupply;

/// @dev counter to allow mutex lock with only one SSTORE operation
uint256 private _guardCounter;
Expand All @@ -19,4 +24,8 @@ contract OZStorage {
return _balances[_investor];
}

function _allowance(address owner, address spender) internal view returns(uint256) {
return _allowed[owner][spender];
}

}
2 changes: 1 addition & 1 deletion contracts/tokens/STGetter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ contract STGetter is OZStorage, SecurityTokenStorage {
* @return Whether the `_operator` is an operator for all partitions of `_tokenHolder`
*/
function isOperator(address _operator, address _tokenHolder) external view returns (bool) {
return (_allowed[_tokenHolder][_operator] == uint(-1));
return (_allowance(_tokenHolder, _operator) == uint(-1));
}

/**
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
"flatten-all": "npm run flatten-modules && npm run flatten-token && npm run flatten-mocks && npm run flatten-oracles && npm run flatten-proxies && npm run flatten && npm run flatten-proxyFactories",
"ethereum-bridge": "node_modules/.bin/ethereum-bridge -H localhost:8545 -a 9 --dev",
"st20generator": "node demo/ST20Generator",
"pretty": "prettier --write --print-width 140 --tab-width 4 \"**/*.js\""
"pretty": "prettier --write --print-width 140 --tab-width 4 \"**/*.js\"",
"st-storage-layout-check": "node scripts/compareStorageLayout.js SecurityToken STGetter"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -84,7 +85,6 @@
"mocha-junit-reporter": "^1.18.0",
"openzeppelin-solidity": "2.2.0",
"prettier": "^1.15.3",
"prompt": "^1.0.0",
"request": "^2.88.0",
"request-promise": "^4.2.2",
"sol-merger": "^0.1.2",
Expand Down
43 changes: 22 additions & 21 deletions scripts/compareStorageLayout.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,48 @@
const fs = require("fs");
const _ = require("underscore");
const solc = require("solc");
const prompt = require("prompt");
const path = require("path");
const util = require("util");
const exec = util.promisify(require("child_process").exec);

console.log(`Mandatory: Solc cli tool should be installed globally. Please put the contract name only`);
prompt.start();
console.log(`Mandatory: Solc cli tool should be installed globally. Please put the contract name only in any order`);

prompt.get(["LogicContract", "ProxyContract"], async (err, result) => {
let temp;
let logicFilePath;
let proxyFilePath;
let contractA = process.argv.slice(2)[0];
let contractB = process.argv.slice(2)[1];

const fileList = walkSync("./contracts", []);
compareStorage(contractA, contractB);

async function compareStorage() {

let paths = findPath(result.LogicContract, result.ProxyContract, fileList);
const fileList = walkSync("./contracts", []);
let paths = findPath(contractA, contractB, fileList);

if (paths.length == 2) {
console.log("Contracts exists \n");

await flatContracts(paths);
let temp;
let logicFilePath = `./flat/${path.basename(paths[0])}`;
let proxyFilePath = `./flat/${path.basename(paths[1])}`;
let contractAPath = `./flat/${path.basename(paths[0])}`;
let contractBPath = `./flat/${path.basename(paths[1])}`;

if (path.basename(paths[0]) === result.LogicContract) {
temp = logicFilePath;
logicFilePath = proxyFilePath;
proxyFilePath = temp;
if (path.basename(paths[0]) === contractA) {
temp = contractAPath;
contractAPath = contractBPath;
contractBPath = temp;
}

let logicAST = await getAST(logicFilePath);
let proxyAST = await getAST(proxyFilePath);
let contractAAST = await getAST(contractAPath);
let contractBAST = await getAST(contractBPath);
// Deleting the temp folder (no longer required)
await flushTemp();

console.log(compareStorageLayouts(parseContract(logicAST), parseContract(proxyAST)));
var result = compareStorageLayouts(parseContract(contractAAST), parseContract(contractBAST));
if (!result)
process.exit(1);
} else {
console.log("Contracts doesn't exists");
}
});
}

function traverseAST(_input, _elements) {
if (_input.children) {
Expand Down Expand Up @@ -101,7 +102,7 @@ function parseContract(input) {
return orderedStateVariables;
}

var walkSync = function(dir, filelist) {
function walkSync(dir, filelist) {
files = fs.readdirSync(dir);
filelist = filelist || [];
files.forEach(function(file) {
Expand All @@ -114,7 +115,7 @@ var walkSync = function(dir, filelist) {
return filelist;
};

var findPath = function(logicContractName, proxyContractName, fileList) {
function findPath(logicContractName, proxyContractName, fileList) {
let paths = new Array();
for (let i = 0; i < fileList.length; i++) {
if (
Expand Down