Skip to content
This repository was archived by the owner on Nov 3, 2020. It is now read-only.
Draft
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
15 changes: 13 additions & 2 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@
{
"files": "*.sol",
"options": {
"printWidth": 80,
"tabWidth": 4,
"printWidth": 120,
"tabWidth": 2,
"useTabs": false,
"singleQuote": false,
"bracketSpacing": false,
"explicitTypes": "always"
}
},
{
"files": "*.ts",
"options": {
"printWidth": 180,
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": true,
"explicitTypes": "always"
}
}
]
}
2 changes: 1 addition & 1 deletion .soliumrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
],
"indentation": [
"error",
4
2
],
"linebreak-style": [
"error",
Expand Down
20 changes: 10 additions & 10 deletions contractAddresses.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"AccountTree": "0xDb4ca41Aa0048F90E73a33eF2b69194b3096E22B",
"ParamManager": "0x24E1331a6BC24305203Ce58fA1Ff707c21DE7198",
"DepositManager": "0x80446876ED0a68952B90941D4765533C924a8235",
"RollupContract": "0x92F6C1485FC82CeDa3C198dEFb47a61843923621",
"ProofOfBurnContract": "0xDa880bd054deA4a5c866F7a919c8b8059DE6354f",
"RollupUtilities": "0xEf4Ec19AdF9B107b5be1f88Ec4d7395B56299b1d",
"NameRegistry": "0x8d7E5E349DDB3dB4c24B80849809602932C8EE00",
"Logger": "0xa961afE298Df64076D18910D094d843b7261574A",
"MerkleTreeUtils": "0x849eC868B8e63bc112eb47F5440945a587E99e29",
"FraudProof": "0xA44dd7c1debc7e69F9026d20032e5d19D94057c2"
"AccountTree": "0xE1c08596DEb9465184820f2815182157db42757B",
"ParamManager": "0x70eE878D560D7E17a986872f54B7C58f564B2784",
"DepositManager": "0x464c94ea90fc7D0D08Bb956cffB9AcfE3AAA5313",
"RollupContract": "0x53b94F9474c01678040BA7da4bc54DCD8c0Ed0BA",
"ProofOfBurnContract": "0x6bf5b6F9b59DF885bD241304C902C5bF7d816fbd",
"RollupUtilities": "0x46E3D301e211d2A2D3148412FCA5788F3182908d",
"NameRegistry": "0x40b13914f9886E234E1e00435E76D558FA8cf5ba",
"Logger": "0x768b5Faed6DC69816f33377d214ffaf00dcDd0cf",
"MerkleTreeUtils": "0x9e8efB8C27f3012493ce315974A64CAcDE6f4ccC",
"FraudProof": "0xFA64858C14345C0a3aD805E0da64900C4d7ec5e6"
}
115 changes: 115 additions & 0 deletions contracts/AccountTree.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
pragma solidity ^0.5.15;

contract AccountTree {
uint256 public constant DEPTH = 31;
uint256 public constant WITNESS_LENGTH = DEPTH;
uint256 public constant SET_SIZE = 1 << DEPTH;
uint256 public constant BATCH_DEPTH = 10;
uint256 public constant BATCH_SIZE = 1 << BATCH_DEPTH;

bytes32 public rootLeft;
bytes32 public rootRight;
bytes32 public root;
uint256 public leafIndexLeft = 0;
uint256 public leafIndexRight = 0;

bytes32[DEPTH] public zeros;
bytes32[DEPTH] public filledSubtreesLeft;
bytes32[DEPTH - BATCH_DEPTH] public filledSubtreesRight;

constructor() public {
for (uint256 i = 1; i < DEPTH; i++) {
zeros[i] = keccak256(abi.encode(zeros[i - 1], zeros[i - 1]));
if (DEPTH > i) {
filledSubtreesLeft[i] = zeros[i];
}
if (BATCH_DEPTH <= i && DEPTH > i) {
filledSubtreesRight[i - BATCH_DEPTH] = zeros[i];
}
}
rootLeft = keccak256(abi.encode(zeros[DEPTH - 1], zeros[DEPTH - 1]));
rootRight = keccak256(abi.encode(zeros[DEPTH - 1], zeros[DEPTH - 1]));
root = keccak256(abi.encode(rootLeft, rootRight));
}

function _updateSingle(bytes32 leaf) internal returns (uint256) {
require(leafIndexLeft < SET_SIZE - 1, "AccountTree: left set is full ");
bytes32 acc = leaf;
uint256 path = leafIndexLeft;
bool subtreeSet = false;
for (uint256 i = 0; i < DEPTH; i++) {
if (path & 1 == 1) {
acc = keccak256(abi.encode(filledSubtreesLeft[i], acc));
} else {
if (!subtreeSet) {
filledSubtreesLeft[i] = acc;
subtreeSet = true;
}
acc = keccak256(abi.encode(acc, zeros[i]));
}
path >>= 1;
}
rootLeft = acc;
root = keccak256(abi.encode(rootLeft, rootRight));
leafIndexLeft += 1;
return leafIndexLeft - 1;
}

function _updateBatch(bytes32[BATCH_SIZE] memory leafs) internal returns (uint256) {
require(leafIndexRight < SET_SIZE - 1 - BATCH_SIZE, "AccountTree: right set is full ");
// require(leafs.length == BATCH_SIZE, "AccountTree: invalid batch size");

// Fill the subtree
for (uint256 i = 0; i < BATCH_DEPTH; i++) {
uint256 n = (BATCH_DEPTH - i - 1);
for (uint256 j = 0; j < 1 << n; j++) {
uint256 k = j << 1;
leafs[j] = keccak256(abi.encode(leafs[k], leafs[k + 1]));
}
}
bytes32 acc = leafs[0];

// Ascend to the root
uint256 path = leafIndexRight;
bool subtreeSet = false;
for (uint256 i = 0; i < DEPTH - BATCH_DEPTH; i++) {
if (path & 1 == 1) {
acc = keccak256(abi.encode(filledSubtreesRight[i], acc));
} else {
if (!subtreeSet) {
filledSubtreesRight[i] = acc;
subtreeSet = true;
}
acc = keccak256(abi.encode(acc, zeros[i + BATCH_DEPTH]));
}
path >>= 1;
}
rootRight = acc;
root = keccak256(abi.encode(rootLeft, rootRight));
leafIndexRight += 1;
return leafIndexRight - 1;
}

function _checkInclusion(
bytes32 leaf,
uint256 leafIndex,
bytes32[WITNESS_LENGTH] memory witness
) internal view returns (bool) {
require(witness.length == DEPTH, "AccountTree: invalid witness size");
uint256 path = leafIndex % SET_SIZE;
bytes32 acc = leaf;
for (uint256 i = 0; i < WITNESS_LENGTH - 1; i++) {
if (path & 1 == 1) {
acc = keccak256(abi.encode(witness[i], acc));
} else {
acc = keccak256(abi.encode(acc, witness[i]));
}
path >>= 1;
}
if (leafIndex < SET_SIZE) {
return acc == rootLeft;
} else {
return acc == rootRight;
}
}
}
35 changes: 35 additions & 0 deletions contracts/BLSAccountRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
pragma solidity ^0.5.15;

import {AccountTree} from "./AccountTree.sol";
import {BLS} from "./libs/BLS.sol";

contract BLSAccountRegistry is AccountTree {
constructor() public AccountTree() {}

function register(uint256[4] calldata pubkey) external returns (uint256) {
require(BLS.isValidPublicKey(pubkey), "BLSAccountTree: invalid pub key");
bytes32 leaf = keccak256(abi.encodePacked(pubkey));
uint256 accountID = _updateSingle(leaf);
return accountID;
}

function registerBatch(uint256[4][BATCH_SIZE] calldata pubkeys) external returns (uint256) {
bytes32[BATCH_SIZE] memory leafs;
for (uint256 i = 0; i < BATCH_SIZE; i++) {
require(BLS.isValidPublicKey(pubkeys[i]), "BLSAccountTree: invalid pub key");
bytes32 leaf = keccak256(abi.encodePacked(pubkeys[i]));
leafs[i] = leaf;
}
uint256 lowerOffset = _updateBatch(leafs);
return lowerOffset;
}

function exists(
uint256 accountIndex,
uint256[4] calldata pubkey,
bytes32[WITNESS_LENGTH] calldata witness
) external view returns (bool) {
bytes32 leaf = keccak256(abi.encodePacked(pubkey));
return _checkInclusion(leaf, accountIndex, witness);
}
}
93 changes: 27 additions & 66 deletions contracts/Deployer.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
pragma solidity ^0.5.15;
import {ParamManager} from "./libs/ParamManager.sol";
import {NameRegistry as Registry} from "./NameRegistry.sol";
import {IncrementalTree} from "./IncrementalTree.sol";
import {DepositManager} from "./DepositManager.sol";
import {TestToken} from "./TestToken.sol";
import {Rollup} from "./rollup.sol";
Expand All @@ -13,69 +12,31 @@ import {Governance} from "./Governance.sol";
// Deployer is supposed to deploy new set of contracts while setting up all the utilities
// libraries and other auxiallry contracts like registry
contract Deployer {
constructor(
address nameregistry,
uint256 maxDepth,
uint256 maxDepositSubTree
) public {
deployContracts(nameregistry, maxDepth, maxDepositSubTree);
}

function deployContracts(
address nameRegistryAddr,
uint256 maxDepth,
uint256 maxDepositSubTree
) public returns (address) {
Registry registry = Registry(nameRegistryAddr);
address governance = address(
new Governance(maxDepth, maxDepositSubTree)
);
require(
registry.registerName(ParamManager.Governance(), governance),
"Could not register governance"
);
address mtUtils = address(new MTUtils(nameRegistryAddr));
require(
registry.registerName(ParamManager.MERKLE_UTILS(), mtUtils),
"Could not register merkle utils tree"
);

address logger = address(new Logger());
require(
registry.registerName(ParamManager.LOGGER(), logger),
"Cannot register logger"
);

address tokenRegistry = address(new TokenRegistry(nameRegistryAddr));
require(
registry.registerName(ParamManager.TOKEN_REGISTRY(), tokenRegistry),
"Cannot register token registry"
);

return nameRegistryAddr;

// deploy accounts tree
// address accountsTree = address(new IncrementalTree(nameRegistryAddr));
// require(
// registry.registerName(ParamManager.ACCOUNTS_TREE(), accountsTree),
// "Could not register accounts tree"
// );

// deposit manager
// address depositManager = address(new DepositManager(nameRegistryAddr));
// require(
// registry.registerName(
// ParamManager.DEPOSIT_MANAGER(),
// depositManager
// ),
// "Cannot register deposit manager"
// );

// // deploy core rollup contract
// address rollup = address(new Rollup(nameRegistryAddr));
// require(
// registry.registerName(ParamManager.ROLLUP_CORE(), rollup),
// "Cannot register core rollup"
// );
}
constructor(
address nameregistry,
uint256 maxDepth,
uint256 maxDepositSubTree
) public {
deployContracts(nameregistry, maxDepth, maxDepositSubTree);
}

function deployContracts(
address nameRegistryAddr,
uint256 maxDepth,
uint256 maxDepositSubTree
) public returns (address) {
Registry registry = Registry(nameRegistryAddr);
address governance = address(new Governance(maxDepth, maxDepositSubTree));
require(registry.registerName(ParamManager.Governance(), governance), "Could not register governance");
address mtUtils = address(new MTUtils(nameRegistryAddr));
require(registry.registerName(ParamManager.MERKLE_UTILS(), mtUtils), "Could not register merkle utils tree");

address logger = address(new Logger());
require(registry.registerName(ParamManager.LOGGER(), logger), "Cannot register logger");

address tokenRegistry = address(new TokenRegistry(nameRegistryAddr));
require(registry.registerName(ParamManager.TOKEN_REGISTRY(), tokenRegistry), "Cannot register token registry");

return nameRegistryAddr;
}
}
Loading