Skip to content

Commit

Permalink
Chore (#158)
Browse files Browse the repository at this point in the history
* Remove openzeppelin and import the few interface files we need.
Remove `Ownable` from `Verifier`.

* Add standalone deploy script, remove migration script

* update yarn.lock

* add compile.js script and use it

* add `setEnforcer` test

* compiler.js: add source to artifact
  • Loading branch information
pinkiebell authored Jul 28, 2019
1 parent cfbd5eb commit 986fda7
Show file tree
Hide file tree
Showing 15 changed files with 500 additions and 4,121 deletions.
2 changes: 1 addition & 1 deletion .solcover.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
compileCommand: '../node_modules/.bin/truffle compile',
compileCommand: '../scripts/compile.js',
testCommand: 'COVERAGE=1 ../node_modules/.bin/mocha --timeout 120000 test/contracts/*',
norpc: true,
deepSkip: true,
Expand Down
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,26 @@ Please make sure to read the contribution guidelines.

## Setup

Currently there are only tests using truffle. You can run the tests like this:
You can run the tests like this:

```
yarn
yarn test
```

### Deployment

`tools/deploy.js` - is a little deployment helper script.

Additionally to the deployment variables you also have to provide the network (the network name in truffle-config).
If the RPC provider does not support signing, you have to supply either `privKey|PRIV_KEY` or `mnemonic|MNEMONIC`
as environment variables to this script.

You can run it like this:
```
network=geth verifierTimeout=1800 taskPeriod=43200 challengePeriod=21600 bondAmount=10000000000000000 maxExecutionDepth=10 ./tools/deploy.js
```

## Runtime - EVMRuntime.sol

The runtime contract is `EVMRuntime.sol`. The contract is designed with extensibility in mind.
Expand Down
14 changes: 10 additions & 4 deletions contracts/Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ pragma experimental ABIEncoderV2;
import "./Enforcer.sol";
import "./HydratedRuntime.sol";
import "./Merkelizer.slb";
import "openzeppelin-solidity/contracts/ownership/Ownable.sol";


contract Verifier is Ownable, HydratedRuntime {
contract Verifier is HydratedRuntime {
using Merkelizer for Merkelizer.ExecutionState;

struct Proofs {
Expand Down Expand Up @@ -82,11 +81,18 @@ contract Verifier is Ownable, HydratedRuntime {

/// @param timeout The time (in seconds) the participants have to react to `submitRound, submitProof`.
/// 30 minutes is a good value for common use-cases.
constructor(uint256 timeout) public Ownable() {
constructor(uint256 timeout) public {
timeoutDuration = timeout;
}

function setEnforcer(address _enforcer) public onlyOwner() {
// Due to the reverse dependency with Enforcer<>Verifier
// we have to first deploy both contracts and peg it to one another.
// Verifier gets deployed first, so Enforcer can be deployed with Verifier's
// address in constructor, but Verifier itself needs to informed about Enforcer's address
// after deployment. Checking if `enforcer` is `address(0)` here does the job.
function setEnforcer(address _enforcer) public {
require(address(enforcer) == address(0));

enforcer = Enforcer(_enforcer);
}

Expand Down
15 changes: 15 additions & 0 deletions contracts/mocks/IERC165.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pragma solidity ^0.5.0;

/**
* @title IERC165
* @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
*/
interface IERC165 {
/**
* @notice Query if a contract implements an interface
* @param interfaceId The interface identifier, as specified in ERC-165
* @dev Interface identification is specified in ERC-165. This function
* uses less than 30,000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
23 changes: 23 additions & 0 deletions contracts/mocks/IERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pragma solidity ^0.5.0;

/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);

function approve(address spender, uint256 value) external returns (bool);

function transferFrom(address from, address to, uint256 value) external returns (bool);

function totalSupply() external view returns (uint256);

function balanceOf(address who) external view returns (uint256);

function allowance(address owner, address spender) external view returns (uint256);

event Transfer(address indexed from, address indexed to, uint256 value);

event Approval(address indexed owner, address indexed spender, uint256 value);
}
27 changes: 27 additions & 0 deletions contracts/mocks/IERC721.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
pragma solidity ^0.5.0;

import "./IERC165.sol";

/**
* @title ERC721 Non-Fungible Token Standard basic interface
* @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
*/
contract IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

function balanceOf(address owner) public view returns (uint256 balance);
function ownerOf(uint256 tokenId) public view returns (address owner);

function approve(address to, uint256 tokenId) public;
function getApproved(uint256 tokenId) public view returns (address operator);

function setApprovalForAll(address operator, bool _approved) public;
function isApprovedForAll(address owner, address operator) public view returns (bool);

function transferFrom(address from, address to, uint256 tokenId) public;
function safeTransferFrom(address from, address to, uint256 tokenId) public;

function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}
4 changes: 2 additions & 2 deletions contracts/mocks/SpendingConditionMock.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pragma solidity ^0.5.2;
pragma experimental ABIEncoderV2;

import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC721/IERC721.sol";
import "./IERC20.sol";
import "./IERC721.sol";


contract SpendingConditionMock {
Expand Down
Empty file removed migrations/.gitkeep
Empty file.
35 changes: 0 additions & 35 deletions migrations/1_deploy.js

This file was deleted.

10 changes: 4 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,19 @@
"lint:sol": "solhint contracts/**/*{.sol,.slb}",
"lint:all": "yarn lint && yarn lint:sol",
"lint:all:fix": "yarn lint:fix && yarn lint:sol",
"compile:contracts": "truffle compile",
"compile:contracts": "scripts/compile.js",
"coverage": "scripts/coverage.sh"
},
"devDependencies": {
"eslint": "=6.0.1",
"ganache-cli": "=6.4.0",
"mocha": "=6.1.4",
"solhint": "=2.1.0",
"truffle": "=5.0.22",
"truffle-hdwallet-provider": "=1.0.14"
"solc": "=0.5.2",
"solhint": "=2.1.0"
},
"dependencies": {
"ethereumjs-vm": "https://github.com/pinkiebell/ethereumjs-vm.git#release/v2.6.0-r6",
"ethers": "=4.0.33",
"keccak": "=2.0.0",
"openzeppelin-solidity": "=2.1.1"
"keccak": "=2.0.0"
}
}
113 changes: 113 additions & 0 deletions scripts/compile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env node

'use strict';

const fs = require('fs');
const { basename } = require('path');
const solc = require('solc');

const contractsDir = 'contracts';
const files = fs.readdirSync(contractsDir);
const sources = {};
let outputDir = '';

['build/', 'contracts'].forEach(
function (dir) {
outputDir += dir;
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir);
}
}
);

while (files.length) {
const file = files.pop();
const path = `${contractsDir}/${file}`;
const stat = fs.statSync(path);

if (stat.isFile() && (file.endsWith('.sol') || file.endsWith('.slb') || file.endsWith('.yul'))) {
const source = fs.readFileSync(path).toString();
const k = basename(path);
sources[k] = { content: source };
process.stdout.write(`> Compiling ${path}\n`);
}

if (stat.isDirectory()) {
fs.readdirSync(path).forEach(
function (p) {
files.push(`${file}/${p}`);
}
);
}
}

const compilerInput = {
language: 'Solidity',
sources: sources,
settings: {
evmVersion: 'constantinople',
optimizer: {
enabled: true,
runs: 2,
},
outputSelection: {
'*': {
'': [
'legacyAST',
'ast',
],
'*': [
'abi',
'metadata',
'evm.bytecode.object',
'evm.bytecode.sourceMap',
'evm.deployedBytecode.object',
'evm.deployedBytecode.sourceMap',
'userdoc',
'devdoc',
],
},
},
},
};

const output = JSON.parse(solc.compile(JSON.stringify(compilerInput)));

if (output.errors) {
output.errors.forEach((obj) => process.stderr.write(obj.formattedMessage));
}

if (!output.contracts) {
process.exit(1);
}

for (const file in output.contracts) {
const contract = output.contracts[file];
const sourceObj = output.sources[file];
const source = sources[file].content;

for (const contractName in contract) {
const obj = contract[contractName];

obj.id = sourceObj.id;
obj.ast = sourceObj.ast;
obj.legacyAST = sourceObj.legacyAST;
obj.source = source;

const evm = obj.evm;
delete obj.evm;

obj.contractName = contractName;
obj.bytecode = `0x${evm.bytecode.object}`;
obj.sourceMap = evm.bytecode.sourceMap;
obj.deployedBytecode = `0x${evm.deployedBytecode.object}`;
obj.deployedSourceMap = evm.deployedBytecode.sourceMap;

const artifactPath = `${outputDir}/${contractName}.json`;

fs.writeFileSync(artifactPath, JSON.stringify(obj, null, 2));
process.stdout.write(`> Artifact for ${contractName} written to ${artifactPath}\n`);
}
}

process.stdout.write(`> Compiled successfully using solc ${solc.version()}\n`);
5 changes: 5 additions & 0 deletions test/contracts/enforcer.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ describe('Enforcer', () => {
proof = solverMerkle.computeResultProof();
});

it('should not allow to `setEnforcer` twice', async () => {
const tx = verifier.setEnforcer(enforcer.address);
await assertRevert(tx);
});

it('should allow to register and challenge execution', async () => {
// register execution and check state
let tx = await enforcer.register(
Expand Down
Loading

0 comments on commit 986fda7

Please sign in to comment.