Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jdkanani
Last active December 18, 2018 08:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdkanani/f616e0ec1add9cc2582de59ef786456d to your computer and use it in GitHub Desktop.
Save jdkanani/f616e0ec1add9cc2582de59ef786456d to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.4.25+commit.59dbf8f1.js&optimize=true&gist=
pragma solidity ^0.4.24;
import "./RLP.sol";
import "./ECVerify.sol";
contract ATestRLP {
using RLP for bytes;
using RLP for RLP.RLPItem;
using RLP for RLP.Iterator;
// chain identifier
bytes32 public constant chain = keccak256("heimdall-A7lVlP");
// round type
bytes32 public constant roundType = keccak256("vote");
// vote type
byte public constant voteType = 0x02;
function encodeData(bytes32 rootHash, uint256 start, uint256 end) public view returns (bytes) {
}
function k(bytes vote) public view returns (bytes32 d) {
d = keccak256(vote);
}
function decodeExtraData(bytes data) public view returns (address proposer, uint256 start, uint256 end, bytes32 root) {
RLP.RLPItem[] memory dataList = data.toRLPItem().toList();
proposer = dataList[0].toAddress();
start = dataList[1].toUint();
end = dataList[2].toUint();
root = dataList[3].toBytes32();
}
function decodeVoteOnly(bytes vote) public view returns (bytes32 c, bytes32 rt, byte v, bytes32 e1) {
RLP.RLPItem[] memory dataList = vote.toRLPItem().toList();
c = keccak256(dataList[0].toData());
rt = keccak256(dataList[1].toData());
v = dataList[4].toByte();
e1 = keccak256(dataList[5].toData());
// e2 = keccak256(bytes20(sha256(extradata)));
}
function decodeDataOnly(bytes extradata) public view returns (bytes32 e2) {
e2 = keccak256(bytes20(sha256(extradata)));
}
function decodeVote(bytes vote, bytes extradata) public view returns (bytes32 c, bytes32 rt, byte v, bytes32 e1, bytes32 e2) {
RLP.RLPItem[] memory dataList = vote.toRLPItem().toList();
c = keccak256(dataList[0].toData());
rt = keccak256(dataList[1].toData());
v = dataList[4].toByte();
e1 = keccak256(dataList[5].toData());
// e2 = keccak256(bytes20(sha256(extradata)));
}
function decodeVote1(bytes data, bytes sig) public view returns (
uint l,
bytes chainId,
bytes roundType,
uint height,
uint round,
bytes extraData,
bytes voteType,
address validator
) {
RLP.RLPItem[] memory dataList = data.toRLPItem().toList();
l = dataList.length;
chainId = dataList[0].toData();
roundType = dataList[1].toData();
height = dataList[2].toUint();
round = dataList[3].toUint();
extraData = dataList[4].toData();
voteType = dataList[5].toData();
// dataList = dataList[4].toRLPItem().toList();
bytes32 hash = keccak256(data);
validator = ECVerify.ecrecovery(hash, sig);
}
}
pragma solidity ^0.4.24;
import { Math } from "./Math.sol";
// TODO: move recursive to iterative
// load in memory and do balancing and rewrite tree
// with just minimum writes can be better
// deleteNode leaves hole in array :D
//
contract AvlTree {
struct Node {
uint256 value;
uint256 left;
uint256 right;
uint256 height;
}
Node[] private tree;
uint256 private root = 0;
uint256 public currentSize = 0;
constructor() public {
// NULL PTR node
tree.push(Node({
value: 0,
left: 0,
right: 0,
height: 0
}));
root = 0;
}
function insert(uint256 value) public returns (uint256) {
require(value > 0);
root = _insert(root, value);
currentSize++;
return root;
}
//should return bool ?
function deleteNode(uint256 value) public {
require(value > 0);
root = _deleteNode(root, value);
currentSize--;
}
function getMin() public view returns (uint256) {
if (root == 0) return 0;
uint256 _root = root;
while (tree[_root].left != 0) {
_root = tree[_root].left;
}
return tree[_root].value;
}
function getTree() public view returns (address[] memory) {
if (root == 0) return new address[](0);
address[] memory _tree = new address[](currentSize);
uint256 j = 0;
uint256 value;
for (uint256 i = 0;i < currentSize;) {
value = tree[j++].value;
if (value > 0) {
value << 160;
_tree[i++] = address(uint160(value));
}
}
return _tree;
}
function getRoot() public view returns(uint256) {
return tree[root].value;
}
function _insert(uint256 _root, uint256 value) private returns (uint256) {
if (_root == 0) {
tree.push(Node({
value: value,
left: 0,
right: 0,
height: 1
}));
return (tree.length - 1);
}
if (value <= tree[_root].value) {
tree[_root].left = _insert(tree[_root].left, value);
} else {
tree[_root].right = _insert(tree[_root].right, value);
}
return balance(_root);
}
function _deleteNode(uint256 _root, uint256 value) private returns (uint256) {
uint256 temp;
if (_root == 0) {
return _root;
}
if (tree[_root].value == value) {
if (tree[_root].left == 0 || tree[_root].right == 0) {
if (tree[_root].left == 0) {
temp = tree[_root].right;
} else {
temp = tree[_root].left;
}
tree[_root] = tree[0];
return temp;
} else {
for (temp = tree[_root].right; tree[temp].left != 0; temp = tree[temp].left){}
tree[_root].value = tree[temp].value;
tree[temp] = tree[0];
tree[_root].right = _deleteNode(tree[_root].right, tree[temp].value);
return balance(_root);
}
}
if (value < tree[_root].value) {
tree[_root].left = _deleteNode(tree[_root].left, value);
} else {
tree[_root].right = _deleteNode(tree[_root].right, value);
}
return balance(_root);
}
function rotateLeft(uint256 _root) private returns (uint256) {
uint256 temp = tree[_root].left;
tree[_root].left = tree[temp].right;
tree[temp].right = _root;
if (_root > 0) {
tree[_root].height = 1 + Math.max(tree[tree[_root].left].height, tree[tree[_root].right].height);
}
if (temp > 0) {
tree[temp].height = 1 + Math.max(tree[tree[temp].left].height, tree[tree[temp].right].height);
}
return temp;
}
function rotateRight (uint256 _root) private returns (uint256) {
uint256 temp = tree[_root].right;
tree[_root].right = tree[temp].left;
tree[temp].left = _root;
if (_root > 0) {
tree[_root].height = 1 + Math.max(tree[tree[_root].left].height, tree[tree[_root].right].height);
}
if (temp > 0) {
tree[temp].height = 1 + Math.max(tree[tree[temp].left].height, tree[tree[temp].right].height);
}
return temp;
}
function balance(uint256 _root) private returns (uint256) {
if (_root > 0) {
tree[_root].height = 1 + Math.max(tree[tree[_root].left].height, tree[tree[_root].right].height);
}
if (tree[tree[_root].left].height > tree[tree[_root].right].height + 1) {
if (tree[tree[tree[_root].left].right].height > tree[tree[tree[_root].left].left].height) {
tree[_root].left = rotateRight(tree[_root].left);
}
return rotateLeft(_root);
} else if (tree[tree[_root].right].height > tree[tree[_root].left].height + 1) {
if (tree[tree[tree[_root].right].left].height > tree[tree[tree[_root].right].right].height) {
tree[_root].right = rotateLeft(tree[_root].right);
}
return rotateRight(_root);
}
return _root;
}
}
pragma solidity 0.4.24;
contract RootMock {
event HeaderBlock(bytes32 root,uint256 start,uint256 end,bytes sigs);
function submitHeaderBlock (bytes32 root, uint256 start, uint256 end ,bytes sigs) public {
emit HeaderBlock(root,start,end,sigs);
}
}
pragma solidity ^0.4.24;
contract BlockTimestamp {
function blockTime() view returns (uint256) {
return block.timestamp;
}
}
pragma solidity ^0.4.24;
library BytesLib {
function concat(
bytes memory _preBytes,
bytes memory _postBytes
) public pure returns (bytes memory) {
bytes memory tempBytes;
assembly {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// Store the length of the first bytes array at the beginning of
// the memory for tempBytes.
let length := mload(_preBytes)
mstore(tempBytes, length)
// Maintain a memory counter for the current write location in the
// temp bytes array by adding the 32 bytes for the array length to
// the starting location.
let mc := add(tempBytes, 0x20)
// Stop copying when the memory counter reaches the length of the
// first bytes array.
let end := add(mc, length)
for {
// Initialize a copy counter to the start of the _preBytes data,
// 32 bytes into its memory.
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
// Increase both counters by 32 bytes each iteration.
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// Write the _preBytes data into the tempBytes memory 32 bytes
// at a time.
mstore(mc, mload(cc))
}
// Add the length of _postBytes to the current length of tempBytes
// and store it as the new length in the first 32 bytes of the
// tempBytes memory.
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
// Move the memory counter back from a multiple of 0x20 to the
// actual end of the _preBytes data.
mc := end
// Stop copying when the memory counter reaches the new combined
// length of the arrays.
end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
// Update the free-memory pointer by padding our last write location
// to 32 bytes: add 31 bytes to the end of tempBytes to move to the
// next 32 byte block, then round down to the nearest multiple of
// 32. If the sum of the length of the two arrays is zero then add
// one before rounding down to leave a blank 32 bytes (the length block with 0).
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31) // Round down to the nearest 32 bytes.
))
}
return tempBytes;
}
function slice(
bytes memory _bytes,
uint _start,
uint _length
) public pure returns (bytes memory) {
require(_bytes.length >= (_start + _length));
bytes memory tempBytes;
assembly {
switch iszero(_length)
case 0 {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// The first word of the slice result is potentially a partial
// word read from the original array. To read it, we calculate
// the length of that partial word and start copying that many
// bytes into the array. The first word we copy will start with
// data we don't care about, but the last `lengthmod` bytes will
// land at the beginning of the contents of the new array. When
// we're done copying, we overwrite the full first word with
// the actual length of the slice.
let lengthmod := and(_length, 31)
// The multiplication in the next line is necessary
// because when slicing multiples of 32 bytes (lengthmod == 0)
// the following copy loop was copying the origin's length
// and then ending prematurely not copying everything it should.
let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
let end := add(mc, _length)
for {
// The multiplication in the next line has the same exact purpose
// as the one above.
let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
mstore(tempBytes, _length)
//update free-memory pointer
//allocating the array padded to 32 bytes like the compiler does now
mstore(0x40, and(add(mc, 31), not(31)))
}
//if we want a zero-length slice let's just return a zero-length array
default {
tempBytes := mload(0x40)
mstore(0x40, add(tempBytes, 0x20))
}
}
return tempBytes;
}
// Pad a bytes array to 32 bytes
function leftPad(bytes memory _bytes) public pure returns (bytes memory) {
bytes memory newBytes = new bytes(32 - _bytes.length);
return concat(newBytes, _bytes);
}
function toBytes32(bytes memory b) public pure returns (bytes32) {
bytes32 out;
for (uint i = 0; i < 32; i++) {
out |= bytes32(b[i] & 0xFF) >> (i * 8);
}
return out;
}
function toBytes4(bytes memory b) public pure returns (bytes4 result) {
assembly {
result := mload(add(b, 32))
}
}
function fromBytes32(bytes32 x) public pure returns (bytes memory) {
bytes memory b = new bytes(32);
for (uint i = 0; i < 32; i++) {
b[i] = byte(uint8(uint(x) / (2**(8*(19 - i)))));
}
return b;
}
function fromUint(uint256 _num) public pure returns (bytes memory _ret) {
assembly {
_ret := mload(0x10)
mstore(_ret, 0x20)
mstore(add(_ret, 0x20), _num)
}
}
function toUint(bytes memory _bytes, uint _start) public pure returns (uint256) {
require(_bytes.length >= (_start + 32));
uint256 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x20), _start))
}
return tempUint;
}
function toAddress(bytes memory _bytes, uint _start) public pure returns (address) {
require(_bytes.length >= (_start + 20));
address tempAddress;
assembly {
tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
}
return tempAddress;
}
}
pragma solidity ^0.4.24;
library ECVerify {
function ecrecoveryFromData(
bytes memory data,
bytes memory sig
) public pure returns (address) {
bytes32 hash = keccak256(data);
return ecrecovery(hash, sig);
}
function ecrecovery(
bytes32 hash,
bytes memory sig
) public pure returns (address) {
bytes32 r;
bytes32 s;
uint8 v;
if (sig.length != 65) {
return address(0x1);
}
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
v := and(mload(add(sig, 65)), 255)
}
// https://github.com/ethereum/go-ethereum/issues/2053
if (v < 27) {
v += 27;
}
if (v != 27 && v != 28) {
return address(0x0);
}
// get address out of hash and signature
address result = ecrecover(hash, v, r, s);
// ecrecover returns zero on error
require(result != address(0x0));
return result;
}
function ecrecovery(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) public pure returns (address) {
// get address out of hash and signature
address result = ecrecover(hash, v, r, s);
// ecrecover returns zero on error
require(result != address(0x0));
return result;
}
function ecverify(
bytes32 hash,
bytes memory sig,
address signer
) public pure returns (bool) {
return signer == ecrecovery(hash, sig);
}
}
pragma solidity ^0.4.24;
contract IRootChain {
// header block
struct HeaderBlock {
bytes32 root;
uint256 start;
uint256 end;
uint256 createdAt;
address proposer;
}
// retrieve current header block
function currentHeaderBlock() public view returns (uint256);
// retrieve current child block
function currentChildBlock() public view returns (uint256);
// get flat header block
function headerBlock(uint256 _headerNumber)
public
view
returns
(
bytes32 _root,
uint256 _start,
uint256 _end,
uint256 _createdAt
);
// get flat deposit block
function depositBlock(uint256 _depositCount)
public
view
returns
(
uint256 _header,
address _owner,
address _token,
uint256 _amount,
uint256 _createdAt
);
// slash
function slash() public;
function transferAmount(
address _token,
address _user,
uint256 _amount,
bool isWeth
) public returns(bool);
}
pragma solidity ^0.4.24;
/**
* @title Math
* @dev Assorted math operations
*/
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Calculates the average of two numbers. Since these are integers,
* averages of an even and odd number cannot be represented, and will be
* rounded down.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow, so we distribute
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}
pragma solidity ^0.4.24;
library Merkle {
function checkMembership(
bytes32 leaf,
uint256 mainIndex,
bytes32 rootHash,
bytes proof
) public pure returns (bool) {
bytes32 proofElement;
bytes32 computedHash = leaf;
uint256 len = (proof.length / 32) * 32;
uint256 index = mainIndex;
for (uint256 i = 32; i <= len; i += 32) {
assembly {
proofElement := mload(add(proof, i))
}
if (index % 2 == 0) {
computedHash = keccak256(computedHash, proofElement);
} else {
computedHash = keccak256(proofElement, computedHash);
}
index = index / 2;
}
return computedHash == rootHash;
}
}
/* solium-disable */
pragma solidity ^0.4.24;
/**
* @title RLPReader
*
* RLPReader is used to read and parse RLP encoded data in memory.
*
* @author Andreas Olofsson (androlo1980@gmail.com)
*/
library RLP {
uint constant DATA_SHORT_START = 0x80;
uint constant DATA_LONG_START = 0xB8;
uint constant LIST_SHORT_START = 0xC0;
uint constant LIST_LONG_START = 0xF8;
uint constant DATA_LONG_OFFSET = 0xB7;
uint constant LIST_LONG_OFFSET = 0xF7;
struct RLPItem {
uint _unsafe_memPtr; // Pointer to the RLP-encoded bytes.
uint _unsafe_length; // Number of bytes. This is the full length of the string.
}
struct Iterator {
RLPItem _unsafe_item; // Item that's being iterated over.
uint _unsafe_nextPtr; // Position of the next item in the list.
}
/* Iterator */
function next(Iterator memory self) internal view returns (RLPItem memory subItem) {
if(hasNext(self)) {
uint256 ptr = self._unsafe_nextPtr;
uint256 itemLength = _itemLength(ptr);
subItem._unsafe_memPtr = ptr;
subItem._unsafe_length = itemLength;
self._unsafe_nextPtr = ptr + itemLength;
}
else
revert();
}
function next(Iterator memory self, bool strict) internal view returns (RLPItem memory subItem) {
subItem = next(self);
if(strict && !_validate(subItem))
revert();
}
function hasNext(Iterator memory self) internal view returns (bool) {
RLP.RLPItem memory item = self._unsafe_item;
return self._unsafe_nextPtr < item._unsafe_memPtr + item._unsafe_length;
}
/* RLPItem */
/// @dev Creates an RLPItem from an array of RLP encoded bytes.
/// @param self The RLP encoded bytes.
/// @return An RLPItem
function toRLPItem(bytes memory self) internal view returns (RLPItem memory) {
uint len = self.length;
if (len == 0) {
return RLPItem(0, 0);
}
uint memPtr;
assembly {
memPtr := add(self, 0x20)
}
return RLPItem(memPtr, len);
}
/// @dev Creates an RLPItem from an array of RLP encoded bytes.
/// @param self The RLP encoded bytes.
/// @param strict Will throw if the data is not RLP encoded.
/// @return An RLPItem
function toRLPItem(bytes memory self, bool strict) internal view returns (RLPItem memory) {
RLP.RLPItem memory item = toRLPItem(self);
if(strict) {
uint len = self.length;
if(_payloadOffset(item) > len)
revert();
if(_itemLength(item._unsafe_memPtr) != len)
revert();
if(!_validate(item))
revert();
}
return item;
}
/// @dev Check if the RLP item is null.
/// @param self The RLP item.
/// @return 'true' if the item is null.
function isNull(RLPItem memory self) internal view returns (bool ret) {
return self._unsafe_length == 0;
}
/// @dev Check if the RLP item is a list.
/// @param self The RLP item.
/// @return 'true' if the item is a list.
function isList(RLPItem memory self) internal view returns (bool ret) {
if (self._unsafe_length == 0)
return false;
uint memPtr = self._unsafe_memPtr;
assembly {
ret := iszero(lt(byte(0, mload(memPtr)), 0xC0))
}
}
/// @dev Check if the RLP item is data.
/// @param self The RLP item.
/// @return 'true' if the item is data.
function isData(RLPItem memory self) internal view returns (bool ret) {
if (self._unsafe_length == 0)
return false;
uint memPtr = self._unsafe_memPtr;
assembly {
ret := lt(byte(0, mload(memPtr)), 0xC0)
}
}
/// @dev Check if the RLP item is empty (string or list).
/// @param self The RLP item.
/// @return 'true' if the item is null.
function isEmpty(RLPItem memory self) internal view returns (bool ret) {
if(isNull(self))
return false;
uint b0;
uint memPtr = self._unsafe_memPtr;
assembly {
b0 := byte(0, mload(memPtr))
}
return (b0 == DATA_SHORT_START || b0 == LIST_SHORT_START);
}
/// @dev Get the number of items in an RLP encoded list.
/// @param self The RLP item.
/// @return The number of items.
function items(RLPItem memory self) internal view returns (uint) {
if (!isList(self))
return 0;
uint b0;
uint memPtr = self._unsafe_memPtr;
assembly {
b0 := byte(0, mload(memPtr))
}
uint pos = memPtr + _payloadOffset(self);
uint last = memPtr + self._unsafe_length - 1;
uint itms;
while(pos <= last) {
pos += _itemLength(pos);
itms++;
}
return itms;
}
/// @dev Create an iterator.
/// @param self The RLP item.
/// @return An 'Iterator' over the item.
function iterator(RLPItem memory self) internal view returns (Iterator memory it) {
require(isList(self));
uint ptr = self._unsafe_memPtr + _payloadOffset(self);
it._unsafe_item = self;
it._unsafe_nextPtr = ptr;
}
/// @dev Return the RLP encoded bytes.
/// @param self The RLPItem.
/// @return The bytes.
function toBytes(RLPItem memory self) internal view returns (bytes memory bts) {
uint256 len = self._unsafe_length;
if (len == 0)
return new bytes(0);
bts = new bytes(len);
_copyToBytes(self._unsafe_memPtr, bts, len);
}
/// @dev Decode an RLPItem into bytes. This will not work if the
/// RLPItem is a list.
/// @param self The RLPItem.
/// @return The decoded string.
function toData(RLPItem memory self) internal view returns (bytes memory bts) {
require(isData(self));
(uint256 rStartPos, uint256 len) = _decode(self);
bts = new bytes(len);
_copyToBytes(rStartPos, bts, len);
}
/// @dev Get the list of sub-items from an RLP encoded list.
/// Warning: This is inefficient, as it requires that the list is read twice.
/// @param self The RLP item.
/// @return Array of RLPItems.
function toList(RLPItem memory self) internal view returns (RLPItem[] memory list) {
require(isList(self));
uint256 numItems = items(self);
list = new RLPItem[](numItems);
RLP.Iterator memory it = iterator(self);
uint idx;
while(hasNext(it)) {
list[idx] = next(it);
idx++;
}
}
/// @dev Decode an RLPItem into an ascii string. This will not work if the
/// RLPItem is a list.
/// @param self The RLPItem.
/// @return The decoded string.
function toAscii(RLPItem memory self) internal view returns (string memory str) {
require(isData(self));
(uint256 rStartPos, uint256 len) = _decode(self);
bytes memory bts = new bytes(len);
_copyToBytes(rStartPos, bts, len);
str = string(bts);
}
/// @dev Decode an RLPItem into a uint. This will not work if the
/// RLPItem is a list.
/// @param self The RLPItem.
/// @return The decoded string.
function toUint(RLPItem memory self) internal view returns (uint data) {
require(isData(self));
(uint256 rStartPos, uint256 len) = _decode(self);
require(len <= 32);
assembly {
data := div(mload(rStartPos), exp(256, sub(32, len)))
}
}
/// @dev Decode an RLPItem into a boolean. This will not work if the
/// RLPItem is a list.
/// @param self The RLPItem.
/// @return The decoded string.
function toBool(RLPItem memory self) internal view returns (bool data) {
require(isData(self));
(uint256 rStartPos, uint256 len) = _decode(self);
require(len == 1);
uint temp;
assembly {
temp := byte(0, mload(rStartPos))
}
require(temp == 1 || temp == 0);
return temp == 1 ? true : false;
}
/// @dev Decode an RLPItem into a byte. This will not work if the
/// RLPItem is a list.
/// @param self The RLPItem.
/// @return The decoded string.
function toByte(RLPItem memory self)
internal
view
returns (byte data)
{
require(isData(self));
(uint256 rStartPos, uint256 len) = _decode(self);
require(len == 1);
uint temp;
assembly {
temp := byte(0, mload(rStartPos))
}
return byte(temp);
}
/// @dev Decode an RLPItem into an int. This will not work if the
/// RLPItem is a list.
/// @param self The RLPItem.
/// @return The decoded string.
function toInt(RLPItem memory self)
internal
view
returns (int data)
{
return int(toUint(self));
}
/// @dev Decode an RLPItem into a bytes32. This will not work if the
/// RLPItem is a list.
/// @param self The RLPItem.
/// @return The decoded string.
function toBytes32(RLPItem memory self)
internal
view
returns (bytes32 data)
{
return bytes32(toUint(self));
}
/// @dev Decode an RLPItem into an address. This will not work if the
/// RLPItem is a list.
/// @param self The RLPItem.
/// @return The decoded string.
function toAddress(RLPItem memory self)
internal
view
returns (address data)
{
require(isData(self));
(uint256 rStartPos, uint256 len) = _decode(self);
require(len == 20);
assembly {
data := div(mload(rStartPos), exp(256, 12))
}
}
// Get the payload offset.
function _payloadOffset(RLPItem memory self)
private
view
returns (uint)
{
if(self._unsafe_length == 0)
return 0;
uint b0;
uint memPtr = self._unsafe_memPtr;
assembly {
b0 := byte(0, mload(memPtr))
}
if(b0 < DATA_SHORT_START)
return 0;
if(b0 < DATA_LONG_START || (b0 >= LIST_SHORT_START && b0 < LIST_LONG_START))
return 1;
if(b0 < LIST_SHORT_START)
return b0 - DATA_LONG_OFFSET + 1;
return b0 - LIST_LONG_OFFSET + 1;
}
// Get the full length of an RLP item.
function _itemLength(uint memPtr)
private
view
returns (uint len)
{
uint b0;
assembly {
b0 := byte(0, mload(memPtr))
}
if (b0 < DATA_SHORT_START)
len = 1;
else if (b0 < DATA_LONG_START)
len = b0 - DATA_SHORT_START + 1;
else if (b0 < LIST_SHORT_START) {
assembly {
let bLen := sub(b0, 0xB7) // bytes length (DATA_LONG_OFFSET)
let dLen := div(mload(add(memPtr, 1)), exp(256, sub(32, bLen))) // data length
len := add(1, add(bLen, dLen)) // total length
}
} else if (b0 < LIST_LONG_START) {
len = b0 - LIST_SHORT_START + 1;
} else {
assembly {
let bLen := sub(b0, 0xF7) // bytes length (LIST_LONG_OFFSET)
let dLen := div(mload(add(memPtr, 1)), exp(256, sub(32, bLen))) // data length
len := add(1, add(bLen, dLen)) // total length
}
}
}
// Get start position and length of the data.
function _decode(RLPItem memory self)
private
view
returns (uint memPtr, uint len)
{
require(isData(self));
uint b0;
uint start = self._unsafe_memPtr;
assembly {
b0 := byte(0, mload(start))
}
if (b0 < DATA_SHORT_START) {
memPtr = start;
len = 1;
return (memPtr, len);
}
if (b0 < DATA_LONG_START) {
len = self._unsafe_length - 1;
memPtr = start + 1;
} else {
uint bLen;
assembly {
bLen := sub(b0, 0xB7) // DATA_LONG_OFFSET
}
len = self._unsafe_length - 1 - bLen;
memPtr = start + bLen + 1;
}
return (memPtr, len);
}
// Assumes that enough memory has been allocated to store in target.
function _copyToBytes(uint btsPtr, bytes memory tgt, uint btsLen)
private
view
{
// Exploiting the fact that 'tgt' was the last thing to be allocated,
// we can write entire words, and just overwrite any excess.
assembly {
{
let i := 0 // Start at arr + 0x20
let words := div(add(btsLen, 31), 32)
let rOffset := btsPtr
let wOffset := add(tgt, 0x20)
tag_loop:
jumpi(end, eq(i, words))
{
let offset := mul(i, 0x20)
mstore(add(wOffset, offset), mload(add(rOffset, offset)))
i := add(i, 1)
}
jump(tag_loop)
end:
mstore(add(tgt, add(0x20, mload(tgt))), 0)
}
}
}
// Check that an RLP item is valid.
function _validate(RLPItem memory self)
private
pure
returns (bool ret)
{
// Check that RLP is well-formed.
uint b0;
uint b1;
uint memPtr = self._unsafe_memPtr;
assembly {
b0 := byte(0, mload(memPtr))
b1 := byte(1, mload(memPtr))
}
if(b0 == DATA_SHORT_START + 1 && b1 < DATA_SHORT_START)
return false;
return true;
}
}
// Library for RLP encoding a list of bytes arrays.
// Modeled after ethereumjs/rlp (https://github.com/ethereumjs/rlp)
// [Very] modified version of Sam Mayo's library.
pragma solidity ^0.4.24;
import "./BytesLib.sol";
library RLPEncode {
// Encode an item (bytes)
function encodeItem(bytes memory self) internal pure returns (bytes memory) {
bytes memory encoded;
if (self.length == 1 && uint(self[0]) < 0x80) {
encoded = new bytes(1);
encoded = self;
} else {
encoded = BytesLib.concat(encodeLength(self.length, 128), self);
}
return encoded;
}
// Encode a list of items
function encodeList(bytes[] memory self) internal pure returns (bytes memory) {
bytes memory encoded;
for (uint i = 0; i < self.length; i++) {
encoded = BytesLib.concat(encoded, encodeItem(self[i]));
}
return BytesLib.concat(encodeLength(encoded.length, 192), encoded);
}
// Hack to encode nested lists. If you have a list as an item passed here, included
// pass = true in that index. E.g.
// [item, list, item] --> pass = [false, true, false]
// function encodeListWithPasses(bytes[] memory self, bool[] pass) internal pure returns (bytes) {
// bytes memory encoded;
// for (uint i=0; i < self.length; i++) {
// if (pass[i] == true) {
// encoded = BytesLib.concat(encoded, self[i]);
// } else {
// encoded = BytesLib.concat(encoded, encodeItem(self[i]));
// }
// }
// return BytesLib.concat(encodeLength(encoded.length, 192), encoded);
// }
// Generate the prefix for an item or the entire list based on RLP spec
function encodeLength(uint256 L, uint256 offset) internal pure returns (bytes memory) {
if (L < 56) {
bytes memory prefix = new bytes(1);
prefix[0] = byte(L + offset);
return prefix;
} else {
// lenLen is the length of the hex representation of the data length
uint lenLen;
uint i = 0x1;
while (L/i != 0) {
lenLen++;
i *= 0x100;
}
bytes memory prefix0 = getLengthBytes(offset + 55 + lenLen);
bytes memory prefix1 = getLengthBytes(L);
return BytesLib.concat(prefix0, prefix1);
}
}
function getLengthBytes(uint256 x) internal pure returns (bytes memory b) {
// Figure out if we need 1 or two bytes to express the length.
// 1 byte gets us to max 255
// 2 bytes gets us to max 65535 (no payloads will be larger than this)
uint256 nBytes = 1;
if (x > 255) {
nBytes = 2;
}
b = new bytes(nBytes);
// Encode the length and return it
for (uint i = 0; i < nBytes; i++) {
b[i] = byte(uint8(x / (2**(8*(nBytes - 1 - i)))));
}
}
}
pragma solidity ^0.4.24;
import { SafeMath } from "./SafeMath.sol";
import { Merkle } from "./Merkle.sol";
import { RLP } from "./RLP.sol";
import { RLPEncode } from "./RLPEncode.sol";
import { IRootChain } from "./IRootChain.sol";
import { StakeManager } from "./StakeManager.sol";
contract IManager {
// chain identifier
bytes32 public chain = keccak256("heimdall-xOUIR0");
// round type
bytes32 public constant roundType = keccak256("vote");
// vote type
byte public constant voteType = 0x02;
// network id
bytes public constant networkId = "\x0d";
// child block interval between checkpoint
uint256 public constant CHILD_BLOCK_INTERVAL = 10000;
}
contract RootChain is IRootChain, IManager {
using SafeMath for uint256;
using Merkle for bytes32;
using RLP for bytes;
using RLP for RLP.RLPItem;
using RLP for RLP.Iterator;
// child chain contract
address public childChainContract;
// list of header blocks (address => header block object)
mapping(uint256 => HeaderBlock) public headerBlocks;
// current header block number
uint256 private _currentHeaderBlock;
// stake interface
StakeManager public stakeManager;
//
// Constructor
//
constructor (address _stakeManager) public {
setStakeManager(_stakeManager);
_currentHeaderBlock = CHILD_BLOCK_INTERVAL;
}
//
// Events
//
event NewHeaderBlock(
address indexed proposer,
uint256 indexed number,
uint256 start,
uint256 end,
bytes32 root
);
//
// External functions
//
function submitHeaderBlock(bytes vote, bytes sigs, bytes extradata) external {
RLP.RLPItem[] memory dataList = vote.toRLPItem().toList();
require(keccak256(dataList[0].toData()) == chain, "Chain ID not same");
require(keccak256(dataList[1].toData()) == roundType, "Round type not same ");
require(dataList[4].toByte() == voteType, "Vote type not same");
// validate extra data using getSha256(extradata)
require(keccak256(dataList[5].toData()) == keccak256(bytes20(sha256(extradata))), "Extra data is invalid");
// extract end and assign to current child
dataList = extradata.toRLPItem().toList();
// fetch start and end
uint256 start = currentChildBlock();
if (start > 0) {
start = start.add(1);
}
uint256 end = dataList[2].toUint();
// Start on mainchain and matic chain must be same
require(start == dataList[1].toUint(), "Start block doesn't match");
// Make sure we are adding blocks
require(end > start, "Not adding blocks");
// check proposer
require(msg.sender == dataList[0].toAddress(), "Invalid proposer");
// Make sure enough validators sign off on the proposed header root
require(stakeManager.checkSignatures(keccak256(vote), sigs), "Sigs are invalid");
// Add the header root
HeaderBlock memory headerBlock = HeaderBlock({
root: dataList[3].toBytes32(),
start: start,
end: end,
createdAt: block.timestamp,
proposer: msg.sender
});
headerBlocks[_currentHeaderBlock] = headerBlock;
// emit new header block
emit NewHeaderBlock(
msg.sender,
_currentHeaderBlock,
headerBlock.start,
headerBlock.end,
dataList[3].toBytes32()
);
// update current header block
_currentHeaderBlock = _currentHeaderBlock.add(CHILD_BLOCK_INTERVAL);
// finalize commit
// stakeManager.finalizeCommit();
// TODO add rewards
}
function setChain(string c) public {
chain = keccak256(c);
}
function currentChildBlock() public view returns(uint256) {
if (_currentHeaderBlock != CHILD_BLOCK_INTERVAL) {
return headerBlocks[_currentHeaderBlock.sub(CHILD_BLOCK_INTERVAL)].end;
}
return 0;
}
function currentHeaderBlock() public view returns (uint256) {
return _currentHeaderBlock;
}
function setFakeHeaderBlock(uint256 start, uint256 end) public {
// Add the header root
HeaderBlock memory headerBlock = HeaderBlock({
root: keccak256(abi.encodePacked(start, end)),
start: start,
end: end,
createdAt: block.timestamp,
proposer: msg.sender
});
headerBlocks[_currentHeaderBlock] = headerBlock;
// update current header block
_currentHeaderBlock = _currentHeaderBlock.add(CHILD_BLOCK_INTERVAL);
}
function headerBlock(uint256 _headerNumber) public view returns (
bytes32 _root,
uint256 _start,
uint256 _end,
uint256 _createdAt
) {
HeaderBlock memory _headerBlock = headerBlocks[_headerNumber];
_root = _headerBlock.root;
_start = _headerBlock.start;
_end = _headerBlock.end;
_createdAt = _headerBlock.createdAt;
}
// get flat deposit block
function depositBlock(uint256 _depositCount)
public
view
returns
(
uint256 _header,
address _owner,
address _token,
uint256 _amount,
uint256 _createdAt
) {}
// set stake manager
function setStakeManager(address _stakeManager) public {
require(_stakeManager != address(0));
stakeManager = StakeManager(_stakeManager);
}
// finalize commit
function finalizeCommit(uint256) public {}
// slash stakers if fraud is detected
function slash() public {
// TODO pass block/proposer
}
function transferAmount(
address _token,
address _user,
uint256 _amount,
bool isWeth
) public returns(bool) {
return true;
}
}
pragma solidity ^0.4.24;
/**
* @title SafeMath
* @dev Math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0); // Solidity only automatically asserts when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two numbers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two numbers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
{
"accounts": {
"account{0}": "0x0cdf0edd304a8e1715d5043d0afe3d3322cc6e3b"
},
"linkReferences": {
"BytesLib": "0x6b9148c2f776dda6f0da52fadaddef837026dcf3",
"ECVerify": "0x42072250056c8296f10851c1b5b5709fcdf814d8"
},
"transactions": [
{
"timestamp": 1545118145078,
"record": {
"value": "0",
"parameters": [],
"abi": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
"contractName": "BytesLib",
"bytecode": "610725610030600b82828239805160001a6073146000811461002057610022565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600436106100af5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166347f5343181146100b45780635f3376f3146101125780637d3d11d01461021157806381cc66081461021c578063ddc4af921461026a578063e0041396146102eb578063e3814b1914610340578063f5e859941461034b578063f647f8fb14610397575b600080fd5b6040805160206004803580820135601f810184900484028501840190955284845261010094369492936024939284019190819084018382808284375094975061040e9650505050505050565b60408051918252519081900360200190f35b6040805160206004803580820135601f810184900484028501840190955284845261019c94369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506104999650505050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101d65781810151838201526020016101be565b50505050905090810190601f1680156102035780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019c600435610514565b6040805160206004803580820135601f810184900484028501840190955284845261010094369492936024939284019190819084018382808284375094975050933594506105c79350505050565b6040805160206004803580820135601f81018490048402850184019095528484526102b69436949293602493928401919081908401838280828437509497506105e79650505050505050565b604080517fffffffff000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b6040805160206004803580820135601f810184900484028501840190955284845261019c9436949293602493928401919081908401838280828437509497505084359550505060209092013591506105ee9050565b61019c60043561066f565b6040805160206004803580820135601f810184900484028501840190955284845261019c9436949293602493928401919081908401838280828437509497506106809650505050505050565b6040805160206004803580820135601f81018490048402850184019095528484526103e594369492936024939284019190819084018382808284375094975050933594506106c99350505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b600080805b60208110156104925780600802848281518110151561042e57fe5b60209101015160029190910a7f0100000000000000000000000000000000000000000000000000000000000000918290049091027fff0000000000000000000000000000000000000000000000000000000000000016049190911790600101610413565b5092915050565b6060806040519050835180825260208201818101602087015b818310156104ca5780518352602092830192016104b2565b50855184518101855292509050808201602086015b818310156104f75780518352602092830192016104df565b509551919091011594909401601f01601f19166040529392505050565b604080516020808252818301909252606091829160009180820161040080388339019050509150600090505b602081101561049257600860138290030260020a8481151561055e57fe5b047f010000000000000000000000000000000000000000000000000000000000000002828281518110151561058f57fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600101610540565b600080826020018451101515156105dd57600080fd5b5050016020015190565b6020015190565b60608082840185511015151561060357600080fd5b8215801561061c57604051915060208201604052610666565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561065557805183526020928301920161063d565b5050858452601f01601f1916604052505b50949350505050565b601051602080825281019190915290565b60608082516020036040519080825280601f01601f1916602001820160405280156106b5578160200160208202803883390190505b5090506106c28184610499565b9392505050565b600080826014018451101515156106df57600080fd5b505001602001516c010000000000000000000000009004905600a165627a7a72305820eae265cf6b4e5b16d1988506c7b2f4be9bf7bada5ec526fcea1e1de3ef99bebb0029",
"inputs": "()",
"type": "constructor",
"from": "account{0}"
}
},
{
"timestamp": 1545118145200,
"record": {
"value": "0",
"parameters": [],
"abi": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a471",
"contractName": "ECVerify",
"bytecode": "61048f610030600b82828239805160001a6073146000811461002057610022565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600436106100785763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166339cdde32811461007d57806377d32e94146100fa57806398ea1c5114610174578063ba0e72521461018b575b600080fd5b60408051602060046024803582810135601f81018590048502860185019096528585526100e69583359536956044949193909101919081908401838280828437509497505050923573ffffffffffffffffffffffffffffffffffffffff16935061021592505050565b604080519115158252519081900360200190f35b60408051602060046024803582810135601f810185900485028601850190965285855261014b9583359536956044949193909101919081908401838280828437509497506102589650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b61014b60043560ff6024351660443560643561035a565b6040805160206004803580820135601f810184900484028501840190955284845261014b94369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506103ef9650505050505050565b60006102218484610258565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161490509392505050565b6000806000806000855160411415156102745760019450610350565b602086015160408701516041880151919550935060ff169150601b82101561029d57601b820191505b8160ff16601b141580156102b557508160ff16601c14155b156102c35760009450610350565b60408051600080825260208083018085528b905260ff8616838501526060830188905260808301879052925160019360a0808501949193601f19840193928390039091019190865af115801561031d573d6000803e3d6000fd5b5050604051601f19015191505073ffffffffffffffffffffffffffffffffffffffff8116151561034c57600080fd5b8094505b5050505092915050565b604080516000808252602080830180855288905260ff871683850152606083018690526080830185905292519092839260019260a08083019392601f19830192908190039091019086865af11580156103b7573d6000803e3d6000fd5b5050604051601f19015191505073ffffffffffffffffffffffffffffffffffffffff811615156103e657600080fd5b95945050505050565b600080836040518082805190602001908083835b602083106104225780518252601f199092019160209182019101610403565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905061045b8184610258565b9493505050505600a165627a7a7230582079c7ab091aee306be640ba81279320db75e796f0b76f166452d6f571760da1ed0029",
"inputs": "()",
"type": "constructor",
"from": "account{0}"
}
},
{
"timestamp": 1545118145344,
"record": {
"value": "0",
"parameters": [
"0x0cdf0edd304a8e1715d5043d0afe3d3322cc6e3b"
],
"abi": "0xdaa77426c30c02a43d9fba4e841a6556c524d47030762eb14dc4af897e605d9b",
"contractName": "StakeManager",
"bytecode": "6080604052600080546001606060020a0319166001606060020a031790556120006001819055670de0b6b3a7640000600290815561010060035562000053919064010000000062002764620000f482021704565b600455600a600555605f6006556002600755600060085560016009553480156200007c57600080fd5b50604051602080620039848339810160405251600160a060020a0381161515620000a557600080fd5b620000af62000119565b604051809103906000f080158015620000cc573d6000803e3d6000fd5b50600a8054600160a060020a031916600160a060020a0392909216919091179055506200012a565b6000808083116200010457600080fd5b82848115156200011057fe5b04949350505050565b60405161107e806200290683390190565b6127cc806200013a6000396000f3006080604052600436106101875763ffffffff60e060020a6000350416630209fdd0811461018c57806304bfb9b5146101f15780630ebb172a146102a157806312102cc9146102c857806316827b1b146102df57806326c0817e146102f75780632def66201461030c57806335dda4981461032157806336ef088c146103365780634b341aed1461035a5780634fd101d71461037b5780635c248855146103905780637033e4a6146103a85780637060054d146103d157806376671808146103e65780637f952d95146103fb578063817b1cd2146104105780638fb80c73146104255780639168ae721461047557806398ee773b146104ca578063a4769071146104e2578063a51af2bb146104f7578063a548c5471461052a578063a7d2c9581461053f578063a7ecd37e146105d6578063ac4746ab146105f7578063ad5a98c51461060c578063ae3a73fe14610649578063bbce8cec14610679578063bf6eac2f1461068e578063e6692f49146106b8578063ed516d51146106d0578063facd743b1461072e575b600080fd5b34801561019857600080fd5b506101a161074f565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156101dd5781810151838201526020016101c5565b505050509050019250505060405180910390f35b3480156101fd57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261028894369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506108919650505050505050565b6040805192835260208301919091528051918290030190f35b3480156102ad57600080fd5b506102b6610c25565b60408051918252519081900360200190f35b3480156102d457600080fd5b506102dd610c2b565b005b3480156102eb57600080fd5b506102dd600435610de0565b34801561030357600080fd5b506102b6610e30565b34801561031857600080fd5b506102dd610e36565b34801561032d57600080fd5b506102dd610e7e565b34801561034257600080fd5b506102dd600160a060020a0360043516602435610f06565b34801561036657600080fd5b506102b6600160a060020a0360043516610fcb565b34801561038757600080fd5b506102b6611001565b34801561039c57600080fd5b50610288600435611007565b3480156103b457600080fd5b506103bd611020565b604080519115158252519081900360200190f35b3480156103dd57600080fd5b506102b6611025565b3480156103f257600080fd5b506102b661102b565b34801561040757600080fd5b506102b6611031565b34801561041c57600080fd5b506102b6611049565b34801561043157600080fd5b50610446600160a060020a036004351661104f565b60408051948552602085019390935283830191909152600160a060020a03166060830152519081900360800190f35b34801561048157600080fd5b50610496600160a060020a0360043516611088565b604080519586526020860194909452848401929092526060840152600160a060020a03166080830152519081900360a00190f35b3480156104d657600080fd5b506102dd6004356110c0565b3480156104ee57600080fd5b506102b66110c5565b34801561050357600080fd5b506102dd600160a060020a03600435811690602435811690604435166064356084356110da565b34801561053657600080fd5b506102b66116c9565b34801561054b57600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101a194369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506116cf9650505050505050565b3480156105e257600080fd5b506102dd600160a060020a0360043516611a64565b34801561060357600080fd5b506102b6611b66565b34801561061857600080fd5b5061062d600160a060020a0360043516611b6c565b60408051600160a060020a039092168252519081900360200190f35b34801561065557600080fd5b506102dd600160a060020a0360043581169060243581169060443516606435611b87565b34801561068557600080fd5b506102b66122bb565b34801561069a57600080fd5b506102dd600160a060020a03600435811690602435166044356122c1565b3480156106c457600080fd5b506102dd6004356122d2565b3480156106dc57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526103bd9583359536956044949193909101919081908401838280828437509497506123229650505050505050565b34801561073a57600080fd5b506103bd600160a060020a0360043516612669565b6060806000600a60009054906101000a9004600160a060020a0316600160a060020a0316631911d1766040518163ffffffff1660e060020a028152600401600060405180830381600087803b1580156107a757600080fd5b505af11580156107bb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156107e457600080fd5b8101908080516401000000008111156107fc57600080fd5b8201602081018481111561080f57600080fd5b815185602082028301116401000000008211171561082c57600080fd5b5090955060009450505050505b815181101561088b57610862828281518110151561085357fe5b90602001906020020151612669565b151561088357818181518110151561087657fe5b6000602091820290920101525b600101610839565b50919050565b6000806000806000806000606060008a6040518082805190602001908083835b602083106108d05780518252601f1990920191602091820191016108b1565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902096506000955060009350600092505b89518367ffffffffffffffff161015610c0a5773__gist/BytesLib.sol:BytesLib____________63e00413968b8560416040518463ffffffff1660e060020a02815260040180806020018467ffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019080838360005b838110156109a257818101518382015260200161098a565b50505050905090810190601f1680156109cf5780820380516001836020036101000a031916815260200191505b5094505050505060006040518083038186803b1580156109ee57600080fd5b505af4158015610a02573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610a2b57600080fd5b810190808051640100000000811115610a4357600080fd5b82016020810184811115610a5657600080fd5b8151640100000000811182820187101715610a7057600080fd5b5050604080517f77d32e94000000000000000000000000000000000000000000000000000000008152600481018d81526024820192835283516044830152835193985073__gist/ECVerify.sol:ECVerify____________96506377d32e9495508d9450889390929160640190602085019080838360005b83811015610b00578181015183820152602001610ae8565b50505050905090810190601f168015610b2d5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015610b4b57600080fd5b505af4158015610b5f573d6000803e3d6000fd5b505050506040513d6020811015610b7557600080fd5b5051600160a060020a038082166000908152600b60205260409020541695509050610b9f85612669565b8015610bbc575083600160a060020a031681600160a060020a0316115b15610bfa57600160a060020a0385166000908152600c60205260409020600101549093508390610bf390879063ffffffff61270216565b9550610bff565b610c0a565b60418301925061090c565b85610c136110c5565b98509850505050505050509250929050565b60045481565b600080610c3733610fcb565b11610c4157600080fd5b600954600454336000908152600c6020526040902060030154610c699163ffffffff61270216565b1115610c7457600080fd5b50336000908152600c6020526040902060010154600854610c9b908263ffffffff61271f16565b600855600a54604080517f41d2a256000000000000000000000000000000000000000000000000000000008152740100000000000000000000000000000000000000008402331760048201529051600160a060020a03909216916341d2a2569160248082019260009290919082900301818387803b158015610d1c57600080fd5b505af1158015610d30573d6000803e3d6000fd5b5050336000818152600c60208181526040808420600481018054600160a060020a03168652600b8452828620805473ffffffffffffffffffffffffffffffffffffffff199081169091558787529484528582556001820186905560028201869055600390910194909455835490921690925560085481518781529283015280519294507f7fc4727e062e336010f2c282598ef5f14facb3de68cf8195c2f23e1454b2b74e9350908290030190a250565b60008111610ded57600080fd5b60055460408051838152602081019290925280517f5d16a900896e1160c2033bc940e6b072d3dc3b6a996fefb9b3b9b9678841824c9281900390910190a1600555565b60025481565b6000610e4133610fcb565b11610e4b57600080fd5b610e7c33610e77610e68600260015461273690919063ffffffff16565b6009549063ffffffff61270216565b610f06565b565b600954600090610e9590600163ffffffff61270216565b6000818152600d60208190526040808320805460098054865283862054909101825560019182018054825487529386208301548787529093019092559084905592935091610eea90849063ffffffff61271f16565b8152602081019190915260400160009081208181556001015550565b600160a060020a0382166000908152600c602052604081206002015481108015610f495750600160a060020a0383166000908152600c6020526040902060030154155b1515610f5457600080fd5b50600160a060020a0382166000818152600c602090815260408083206001808201546003909201879055868552600d909352818420805482900381559092018054600019019055519092849284927fcde3813e379342e7506ca1f984065c81821e879aebd4be83cb35b5ab976518f99190a4505050565b6000600160a060020a0382161515610fe257600080fd5b50600160a060020a03166000908152600c602052604090206001015490565b60055481565b600d602052600090815260409020805460019091015482565b600090565b60015481565b60095481565b6009546000908152600d602052604090206001015490565b60085481565b600160a060020a039081166000908152600c60205260409020600181015460028201546003830154600490930154919490939190911690565b600c602052600090815260409020805460018201546002830154600384015460049094015492939192909190600160a060020a031685565b600755565b6009546000908152600d602052604090205490565b600160a060020a0385166000908152600c6020526040812054819081901561114c576040805160e560020a62461bcd02815260206004820152601660248201527f4e6f207365636f6e642074696d65207374616b696e6700000000000000000000604482015290519081900360640190fd5b600a60009054906101000a9004600160a060020a0316600160a060020a031663bda1504b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561119f57600080fd5b505af11580156111b3573d6000803e3d6000fd5b505050506040513d60208110156111c957600080fd5b505160055460020211611226576040805160e560020a62461bcd02815260206004820152601260248201527f56616c696461746f72207365742066756c6c0000000000000000000000000000604482015290519081900360640190fd5b6000546bffffffffffffffffffffffff16851061128d576040805160e560020a62461bcd02815260206004820152601060248201527f53746179207265616c6973746963212100000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a038616158015906112bd5750600160a060020a038681166000908152600b602052604090205416155b1515611313576040805160e560020a62461bcd02815260206004820152600f60248201527f416c72656164792070726573656e740000000000000000000000000000000000604482015290519081900360640190fd5b600a60009054906101000a9004600160a060020a0316600160a060020a031663d6362e976040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561136657600080fd5b505af115801561137a573d6000803e3d6000fd5b505050506040513d602081101561139057600080fd5b5051925082156113de5760065474010000000000000000000000000000000000000000909304926113db906064906113cf90869063ffffffff61273616565b9063ffffffff61276416565b92505b6113ea83600254612787565b92508285101561146a576040805160e560020a62461bcd02815260206004820152602c60248201527f5374616b652073686f756c64206265206774207468656e205825206f6620637560448201527f7272656e74206c6f776573740000000000000000000000000000000000000000606482015290519081900360840190fd5b60085461147d908663ffffffff61270216565b60088190555060a0604051908101604052806009548152602001868152602001600081526020016000815260200187600160a060020a0316815250600c60008a600160a060020a0316600160a060020a031681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a815481600160a060020a030219169083600160a060020a0316021790555090505087600b600088600160a060020a0316600160a060020a0316815260200190815260200160002060006101000a815481600160a060020a030219169083600160a060020a0316021790555087600160a060020a031660a0869060020a02179150600a60009054906101000a9004600160a060020a0316600160a060020a03166390b5561d836040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b1580156115f257600080fd5b505af1158015611606573d6000803e3d6000fd5b505050506040513d602081101561161c57600080fd5b505050600160a060020a038087166000908152600c60208181526040808420600381018990558c86168086528286206002018a81556001928301548b8852600d865284882080548e019190910381558301805490930190925594859052928252915460085483518a815292830152825188959194918b169391927fad3fa07f4195b47e64892eb944ecbfc253384053c119852bb2bcae484c2fcb6992908290030190a45050505050505050565b60075481565b60606000606060008060606000886040518082805190602001908083835b6020831061170c5780518252601f1990920191602091820191016116ed565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902095506041885181151561174857fe5b04600101604051908082528060200260200182016040528015611775578160200160208202803883390190505b50945060009350600092505b87518367ffffffffffffffff161015611a575773__gist/BytesLib.sol:BytesLib____________63e0041396898560416040518463ffffffff1660e060020a02815260040180806020018467ffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019080838360005b838110156118175781810151838201526020016117ff565b50505050905090810190601f1680156118445780820380516001836020036101000a031916815260200191505b5094505050505060006040518083038186803b15801561186357600080fd5b505af4158015611877573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156118a057600080fd5b8101908080516401000000008111156118b857600080fd5b820160208101848111156118cb57600080fd5b81516401000000008111828201871017156118e557600080fd5b5050604080517f77d32e94000000000000000000000000000000000000000000000000000000008152600481018c81526024820192835283516044830152835193985073__gist/ECVerify.sol:ECVerify____________96506377d32e9495508c9450889390929160640190602085019080838360005b8381101561197557818101518382015260200161195d565b50505050905090810190601f1680156119a25780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b1580156119c057600080fd5b505af41580156119d4573d6000803e3d6000fd5b505050506040513d60208110156119ea57600080fd5b50519050600160a060020a038085169082161115611a47579250828085604167ffffffffffffffff86160467ffffffffffffffff16815181101515611a2b57fe5b600160a060020a03909216602092830290910190910152611a4c565b611a57565b604183019250611781565b5092979650505050505050565b6000611a6f33610fcb565b11611a7957600080fd5b600160a060020a03811615801590611aa95750600160a060020a038181166000908152600b602052604090205416155b1515611ab457600080fd5b336000818152600c6020526040808220600401549051600160a060020a03808616949216927ff63941bc0485c6b62a7130aa6d00b03821bd7de6dffb0a92d5eb66ef34fad2a591a4336000818152600c602081815260408084206004018054600160a060020a039081168652600b8452828620805473ffffffffffffffffffffffffffffffffffffffff1990811690915597168086529185208054881687179055949093525281549092169091179055565b60035481565b600b60205260009081526040902054600160a060020a031681565b600160a060020a0384166000908152600c60205260408120548190819015611bf9576040805160e560020a62461bcd02815260206004820152601660248201527f4e6f207365636f6e642074696d65207374616b696e6700000000000000000000604482015290519081900360640190fd5b600a60009054906101000a9004600160a060020a0316600160a060020a031663bda1504b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611c4c57600080fd5b505af1158015611c60573d6000803e3d6000fd5b505050506040513d6020811015611c7657600080fd5b505160055460020211611cd3576040805160e560020a62461bcd02815260206004820152601260248201527f56616c696461746f72207365742066756c6c0000000000000000000000000000604482015290519081900360640190fd5b6000546bffffffffffffffffffffffff168410611d3a576040805160e560020a62461bcd02815260206004820152601060248201527f53746179207265616c6973746963212100000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03851615801590611d6a5750600160a060020a038581166000908152600b602052604090205416155b1515611d7557600080fd5b600a60009054906101000a9004600160a060020a0316600160a060020a031663d6362e976040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015611dc857600080fd5b505af1158015611ddc573d6000803e3d6000fd5b505050506040513d6020811015611df257600080fd5b505192508215611e34576006547401000000000000000000000000000000000000000090930492611e31906064906113cf90869063ffffffff61273616565b92505b611e4083600254612787565b925082841015611ec0576040805160e560020a62461bcd02815260206004820152602c60248201527f5374616b652073686f756c64206265206774207468656e205825206f6620637560448201527f7272656e74206c6f776573740000000000000000000000000000000000000000606482015290519081900360840190fd5b600854611ed3908563ffffffff61270216565b60088190555060a0604051908101604052806009548152602001858152602001600081526020016000815260200186600160a060020a0316815250600c600089600160a060020a0316600160a060020a031681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a815481600160a060020a030219169083600160a060020a0316021790555090505086600b600087600160a060020a0316600160a060020a0316815260200190815260200160002060006101000a815481600160a060020a030219169083600160a060020a0316021790555086600160a060020a031660a0859060020a02179150600a60009054906101000a9004600160a060020a0316600160a060020a03166390b5561d836040518263ffffffff1660e060020a02815260040180828152602001915050602060405180830381600087803b15801561204857600080fd5b505af115801561205c573d6000803e3d6000fd5b505050506040513d602081101561207257600080fd5b50506005546009546000908152600d602052604090206001015410156120de5760098054600160a060020a0389166000908152600c60209081526040808320600201849055928252600d9052818120805488019055915482529020600190810180549091019055612255565b600160a060020a0386166000908152600c6020526040902054151561210257600080fd5b600160a060020a0386166000908152600c6020526040902060020154158015906121455750600160a060020a0386166000908152600c6020526040902060030154155b151561215057600080fd5b600160a060020a038087166000908152600c6020526040808220600190810154938b168352912001541161218357600080fd5b600160a060020a0386166000818152600c6020526040902060019081015490547401000000000000000000000000000000000000000090910290911792506121d690610e6890600263ffffffff61273616565b600160a060020a038088166000818152600c6020818152604080842060038101889055958e16845280842060020187905560019095018054878552600d835286852080548d0191909103905584845291905254925193945084937fcde3813e379342e7506ca1f984065c81821e879aebd4be83cb35b5ab976518f99190a45b600160a060020a038088166000818152600c60209081526040918290206002015460085483518a815292830152825190948a1693927fad3fa07f4195b47e64892eb944ecbfc253384053c119852bb2bcae484c2fcb69928290030190a450505050505050565b60065481565b6122cd33848484611b87565b505050565b600081116122df57600080fd5b60015460408051838152602081019290925280517f9444bfcfa6aed72a15da73de1220dcc07d7864119c44abfec0037bbcacefda989281900390910190a1600155565b6000808080806060815b87518367ffffffffffffffff16101561262a5773__gist/BytesLib.sol:BytesLib____________63e0041396898560416040518463ffffffff1660e060020a02815260040180806020018467ffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019080838360005b838110156123c25781810151838201526020016123aa565b50505050905090810190601f1680156123ef5780820380516001836020036101000a031916815260200191505b5094505050505060006040518083038186803b15801561240e57600080fd5b505af4158015612422573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561244b57600080fd5b81019080805164010000000081111561246357600080fd5b8201602081018481111561247657600080fd5b815164010000000081118282018710171561249057600080fd5b5050604080517f77d32e94000000000000000000000000000000000000000000000000000000008152600481018f81526024820192835283516044830152835193985073__gist/ECVerify.sol:ECVerify____________96506377d32e9495508f9450889390929160640190602085019080838360005b83811015612520578181015183820152602001612508565b50505050905090810190601f16801561254d5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561256b57600080fd5b505af415801561257f573d6000803e3d6000fd5b505050506040513d602081101561259557600080fd5b5051600160a060020a038082166000908152600b602052604090205416955090506125bf85612669565b80156125dc575083600160a060020a031681600160a060020a0316115b1561261a57600160a060020a0385166000908152600c6020526040902060010154909350839061261390879063ffffffff61270216565b955061261f565b61262a565b60418301925061232c565b612659600161264d60036113cf60026126416110c5565b9063ffffffff61273616565b9063ffffffff61270216565b9095101598975050505050505050565b600160a060020a0381166000908152600c6020526040812060010154811080156126b05750600954600160a060020a0383166000908152600c602052604090206002015411155b80156126fc5750600160a060020a0382166000908152600c602052604090206003015415806126fc5750600954600160a060020a0383166000908152600c602052604090206003015410155b92915050565b60008282018381101561271457600080fd5b8091505b5092915050565b6000808383111561272f57600080fd5b5050900390565b6000808315156127495760009150612718565b5082820282848281151561275957fe5b041461271457600080fd5b60008080831161277357600080fd5b828481151561277e57fe5b04949350505050565b6000818310156127975781612799565b825b93925050505600a165627a7a7230582042ad95c75b243ac7798d7ada3d8c2b16f7a14db215f65bbc823cb7ac5a1d3d14002960806040526000600155600060025534801561001a57600080fd5b506040805160808101825260008082526020820181815292820181815260608301828152825460018181018555848052945160049091027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56381019190915594517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56486015590517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e565850155517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5669093019290925555610f81806100fd6000396000f3006080604052600436106100775763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631911d176811461007c57806341d2a256146100e15780635ca1e165146100fb57806390b5561d14610122578063bda1504b1461013a578063d6362e971461014f575b600080fd5b34801561008857600080fd5b50610091610164565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156100cd5781810151838201526020016100b5565b505050509050019250505060405180910390f35b3480156100ed57600080fd5b506100f9600435610243565b005b34801561010757600080fd5b5061011061026c565b60408051918252519081900360200190f35b34801561012e57600080fd5b50610110600435610295565b34801561014657600080fd5b506101106102c5565b34801561015b57600080fd5b506101106102cb565b60608060008060006001546000141561018d57604080516000815260208101909152945061023c565b6002546040519080825280602002602001820160405280156101b9578160200160208202803883390190505b50935060009250600090505b600254811015610238576000805460018501949081106101e157fe5b60009182526020822060049091020154925082111561023357835160018201918391869190811061020e57fe5b73ffffffffffffffffffffffffffffffffffffffff9092166020928302909101909101525b6101c5565b8394505b5050505090565b6000811161025057600080fd5b61025c6001548261035e565b6001555060028054600019019055565b60008060015481548110151561027e57fe5b906000526020600020906004020160000154905090565b60008082116102a357600080fd5b6102af6001548361072f565b600181815560028054909101905590505b919050565b60025481565b600080600154600014156102e2576000915061035a565b506001545b60008054829081106102f557fe5b906000526020600020906004020160010154600014151561033757600080548290811061031e57fe5b90600052602060002090600402016001015490506102e7565b600080548290811061034557fe5b90600052602060002090600402016000015491505b5090565b60008083151561037057839150610728565b8260008581548110151561038057fe5b90600052602060002090600402016000015414156106555760008054859081106103a657fe5b906000526020600020906004020160010154600014806103e5575060008054859081106103cf57fe5b9060005260206000209060040201600201546000145b156104c15760008054859081106103f857fe5b9060005260206000209060040201600101546000141561043957600080548590811061042057fe5b906000526020600020906004020160020154905061045c565b600080548590811061044757fe5b90600052602060002090600402016001015490505b600080548190811061046a57fe5b906000526020600020906004020160008581548110151561048757fe5b6000918252602090912082546004909202019081556001808301549082015560028083015490820155600391820154910155905080610728565b60008054859081106104cf57fe5b90600052602060002090600402016002015490505b60008054829081106104f257fe5b906000526020600020906004020160010154600014151561053457600080548290811061051b57fe5b90600052602060002090600402016001015490506104e4565b600080548290811061054257fe5b90600052602060002090600402016000015460008581548110151561056357fe5b6000918252602082206004909102019190915580548190811061058257fe5b906000526020600020906004020160008281548110151561059f57fe5b9060005260206000209060040201600082015481600001556001820154816001015560028201548160020155600382015481600301559050506106226000858154811015156105ea57fe5b90600052602060002090600402016002015460008381548110151561060b57fe5b90600052602060002090600402016000015461035e565b600080548690811061063057fe5b90600052602060002090600402016002018190555061064e846108ea565b9150610728565b600080548590811061066357fe5b9060005260206000209060040201600001548310156106ce576106a660008581548110151561068e57fe5b9060005260206000209060040201600101548461035e565b60008054869081106106b457fe5b90600052602060002090600402016001018190555061071c565b6106f86000858154811015156106e057fe5b9060005260206000209060040201600201548461035e565b600080548690811061070657fe5b9060005260206000209060040201600201819055505b610725846108ea565b91505b5092915050565b60008215156108135750604080516080810182528281526000602082018181529282018181526001606084018181528354918201845583805293517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56360049092029182015593517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564850155517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56584015590517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5669092019190915554600019016108e4565b600080548490811061082157fe5b6000918252602090912060049091020154821161088a5761086260008481548110151561084a57fe5b9060005260206000209060040201600101548361072f565b600080548590811061087057fe5b9060005260206000209060040201600101819055506108d8565b6108b460008481548110151561089c57fe5b9060005260206000209060040201600201548361072f565b60008054859081106108c257fe5b9060005260206000209060040201600201819055505b6108e1836108ea565b90505b92915050565b6000808211156109a45761097c6000808481548110151561090757fe5b90600052602060002090600402016001015481548110151561092557fe5b9060005260206000209060040201600301546000808581548110151561094757fe5b90600052602060002090600402016002015481548110151561096557fe5b906000526020600020906004020160030154610cf5565b60010160008381548110151561098e57fe5b9060005260206000209060040201600301819055505b600080838154811015156109b457fe5b9060005260206000209060040201600201548154811015156109d257fe5b906000526020600020906004020160030154600101600080848154811015156109f757fe5b906000526020600020906004020160010154815481101515610a1557fe5b9060005260206000209060040201600301541115610b5057600080600084815481101515610a3f57fe5b906000526020600020906004020160010154815481101515610a5d57fe5b906000526020600020906004020160010154815481101515610a7b57fe5b906000526020600020906004020160030154600080600085815481101515610a9f57fe5b906000526020600020906004020160010154815481101515610abd57fe5b906000526020600020906004020160020154815481101515610adb57fe5b9060005260206000209060040201600301541115610b4057610b1c600083815481101515610b0557fe5b906000526020600020906004020160010154610d0c565b6000805484908110610b2a57fe5b9060005260206000209060040201600101819055505b610b4982610ea9565b90506102c0565b60008083815481101515610b6057fe5b906000526020600020906004020160010154815481101515610b7e57fe5b90600052602060002090600402016003015460010160008084815481101515610ba357fe5b906000526020600020906004020160020154815481101515610bc157fe5b906000526020600020906004020160030154111561035a57600080600084815481101515610beb57fe5b906000526020600020906004020160020154815481101515610c0957fe5b906000526020600020906004020160020154815481101515610c2757fe5b906000526020600020906004020160030154600080600085815481101515610c4b57fe5b906000526020600020906004020160020154815481101515610c6957fe5b906000526020600020906004020160010154815481101515610c8757fe5b9060005260206000209060040201600301541115610cec57610cc8600083815481101515610cb157fe5b906000526020600020906004020160020154610ea9565b6000805484908110610cd657fe5b9060005260206000209060040201600201819055505b610b4982610d0c565b600081831015610d0557816108e1565b5090919050565b600080600083815481101515610d1e57fe5b9060005260206000209060040201600201549050600081815481101515610d4157fe5b906000526020600020906004020160010154600084815481101515610d6257fe5b90600052602060002090600402016002018190555082600082815481101515610d8757fe5b9060005260206000209060040201600101819055506000831115610e2057610df860008085815481101515610db857fe5b906000526020600020906004020160010154815481101515610dd657fe5b9060005260206000209060040201600301546000808681548110151561094757fe5b600101600084815481101515610e0a57fe5b9060005260206000209060040201600301819055505b60008111156108e457610e7c60008083815481101515610e3c57fe5b906000526020600020906004020160010154815481101515610e5a57fe5b9060005260206000209060040201600301546000808481548110151561094757fe5b600101600082815481101515610e8e57fe5b90600052602060002090600402016003018190555092915050565b600080600083815481101515610ebb57fe5b9060005260206000209060040201600101549050600081815481101515610ede57fe5b906000526020600020906004020160020154600084815481101515610eff57fe5b90600052602060002090600402016001018190555082600082815481101515610f2457fe5b9060005260206000209060040201600201819055506000831115610e2057610df860008085815481101515610db857fe00a165627a7a7230582028a50c124f851fa44e6b74a51c45f799f418465a7140b473cb95353f75cba6a90029",
"linkReferences": {
"gist/BytesLib.sol": {
"BytesLib": [
{
"length": 20,
"start": 2651
},
{
"length": 20,
"start": 6352
},
{
"length": 20,
"start": 9339
}
]
},
"gist/ECVerify.sol": {
"ECVerify": [
{
"length": 20,
"start": 3055
},
{
"length": 20,
"start": 6756
},
{
"length": 20,
"start": 9743
}
]
}
},
"name": "",
"inputs": "(address)",
"type": "constructor",
"from": "account{0}"
}
},
{
"timestamp": 1545118165844,
"record": {
"value": "0",
"parameters": [
"0x77732829ad18d73a558e3ad8e4a28a6fa87f9cc2"
],
"abi": "0x5a657105c493a1213c976c653e929218bb4a516bca307dce5861ec23fffa4e58",
"contractName": "RootChain",
"bytecode": "608060408190527f6865696d64616c6c2d784f55495230000000000000000000000000000000000090527fb3f9989a5c32ba38b27f2196a41c5eca1fa36c21938915939aeeed0bbf7a585960005534801561005957600080fd5b506040516020806117d6833981016040525161007d81640100000000610089810204565b506127106003556100c0565b600160a060020a038116151561009e57600080fd5b60048054600160a060020a031916600160a060020a0392909216919091179055565b611707806100cf6000396000f3006080604052600436106101065763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630e7c67fc811461010b578063242fbb041461012e5780632c2d1a3b1461015f5780632da25de314610186578063325906541461019b5780633e2196ca146101ea57806341539d4a1461022d57806344a77d961461027957806361bbd461146102945780637542ff95146102d25780637a95f1e8146102e75780637d1a3d37146102fc5780639025e64c146103465780639d68ce53146103d0578063a831fa0714610429578063c763e5a11461043e578063ec7e485514610453578063ec83d3ba14610468578063fb0df30f146104a0575b600080fd5b34801561011757600080fd5b5061012c600160a060020a03600435166104b8565b005b34801561013a57600080fd5b506101436104fc565b60408051600160a060020a039092168252519081900360200190f35b34801561016b57600080fd5b5061017461050b565b60408051918252519081900360200190f35b34801561019257600080fd5b5061012c610540565b3480156101a757600080fd5b506101b3600435610542565b60408051958652600160a060020a039485166020870152929093168483015260608401526080830191909152519081900360a00190f35b3480156101f657600080fd5b50610219600160a060020a03600435811690602435166044356064351515610550565b604080519115158252519081900360200190f35b34801561023957600080fd5b5061024560043561055a565b604080519586526020860194909452848401929092526060840152600160a060020a03166080830152519081900360a00190f35b34801561028557600080fd5b5061012c600435602435610592565b3480156102a057600080fd5b506102ac6004356106bf565b604080519485526020850193909352838301919091526060830152519081900360800190f35b3480156102de57600080fd5b5061014361072f565b3480156102f357600080fd5b5061017461073e565b34801561030857600080fd5b50610311610787565b604080517fff000000000000000000000000000000000000000000000000000000000000009092168252519081900360200190f35b34801561035257600080fd5b5061035b6107ab565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561039557818101518382015260200161037d565b50505050905090810190601f1680156103c25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103dc57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261012c9436949293602493928401919081908401838280828437509497506107e29650505050505050565b34801561043557600080fd5b50610174610844565b34801561044a57600080fd5b5061017461084a565b34801561045f57600080fd5b50610174610850565b34801561047457600080fd5b5061012c6024600480358281019290820135918135808301929082013591604435918201910135610856565b3480156104ac57600080fd5b5061012c60043561109e565b600160a060020a03811615156104cd57600080fd5b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600154600160a060020a031681565b604080517f766f7465000000000000000000000000000000000000000000000000000000008152905190819003600401902081565b565b506000908190819081908190565b6001949350505050565b6002602081905260009182526040909120805460018201549282015460038301546004909301549193929091600160a060020a031685565b61059a611675565b6040805160a08101825260c0810185905260e080820185905282518083039091018152610100820192839052805191928392819060208401908083835b602083106105f65780518252601f1990920191602091820191016105d7565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528581018a905285830189905242606080880191909152336080978801526003805460009081526002808552908690208a518155938a01516001850155948901519483019490945587015181840155948601516004909501805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0390961695909517909455549394506106b79392506127109150506110a1565b600355505050565b6000806000806106cd611675565b5050506000928352505060026020818152604092839020835160a0810185528154808252600183015493820184905293820154948101859052600382015460608201819052600490920154600160a060020a0316608090910152919390929190565b600454600160a060020a031681565b6003546000906127101461078057600260006107676127106003546110ba90919063ffffffff16565b8152602001908152602001600020600201549050610784565b5060005b90565b7f020000000000000000000000000000000000000000000000000000000000000081565b60408051808201909152600181527f0d00000000000000000000000000000000000000000000000000000000000000602082015281565b806040518082805190602001908083835b602083106108125780518252601f1990920191602091820191016107f3565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912060005550505050565b61271081565b60005481565b60035490565b6060600080610863611675565b6108a461089f8b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437506110d1945050505050565b611124565b600080548251929650916108cb91879181106108bc57fe5b906020019060200201516111d9565b6040518082805190602001908083835b602083106108fa5780518252601f1990920191602091820191016108db565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916141515610982576040805160e560020a62461bcd02815260206004820152601160248201527f436861696e204944206e6f742073616d65000000000000000000000000000000604482015290519081900360640190fd5b604080517f766f7465000000000000000000000000000000000000000000000000000000008152905190819003600401902084516109c790869060019081106108bc57fe5b6040518082805190602001908083835b602083106109f65780518252601f1990920191602091820191016109d7565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916141515610a7e576040805160e560020a62461bcd02815260206004820152601460248201527f526f756e642074797065206e6f742073616d6520000000000000000000000000604482015290519081900360640190fd5b83517f020000000000000000000000000000000000000000000000000000000000000090610ac29086906004908110610ab357fe5b9060200190602002015161123b565b7fff000000000000000000000000000000000000000000000000000000000000001614610b39576040805160e560020a62461bcd02815260206004820152601260248201527f566f74652074797065206e6f742073616d650000000000000000000000000000604482015290519081900360640190fd5b60028686604051808383808284378201915050925050506020604051808303816000865af1158015610b6f573d6000803e3d6000fd5b5050506040513d6020811015610b8457600080fd5b5051604080516bffffffffffffffffffffffff199092168252519081900360140190208451610bba90869060059081106108bc57fe5b6040518082805190602001908083835b60208310610be95780518252601f199092019160209182019101610bca565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916141515610c71576040805160e560020a62461bcd02815260206004820152601560248201527f4578747261206461746120697320696e76616c69640000000000000000000000604482015290519081900360640190fd5b610cad61089f87878080601f016020809104026020016040519081016040528093929190818152602001838380828437506110d1945050505050565b9350610cb761073e565b92506000831115610cd657610cd383600163ffffffff6110a116565b92505b610cf7846002815181101515610ce857fe5b9060200190602002015161129e565b9150610d0b846001815181101515610ce857fe5b8314610d61576040805160e560020a62461bcd02815260206004820152601960248201527f537461727420626c6f636b20646f65736e2774206d6174636800000000000000604482015290519081900360640190fd5b828211610db8576040805160e560020a62461bcd02815260206004820152601160248201527f4e6f7420616464696e6720626c6f636b73000000000000000000000000000000604482015290519081900360640190fd5b610dd9846000815181101515610dca57fe5b906020019060200201516112e7565b600160a060020a03163314610e38576040805160e560020a62461bcd02815260206004820152601060248201527f496e76616c69642070726f706f73657200000000000000000000000000000000604482015290519081900360640190fd5b600454604051600160a060020a039091169063ed516d51908c908c908083838082843782019150509250505060405180910390208a8a6040518463ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018084600019166000191681526020018060200182810382528484828181526020019250808284378201915050945050505050602060405180830381600087803b158015610ee857600080fd5b505af1158015610efc573d6000803e3d6000fd5b505050506040513d6020811015610f1257600080fd5b50511515610f6a576040805160e560020a62461bcd02815260206004820152601060248201527f536967732061726520696e76616c696400000000000000000000000000000000604482015290519081900360640190fd5b60a060405190810160405280610f97866003815181101515610f8857fe5b90602001906020020151611333565b81526020808201869052604080830186905242606080850191909152336080948501819052600380546000908152600280875290859020885181559588015160018701819055948801519086018190559287015185820155948601516004909401805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0390951694909417909355835489519596509492937ff146921b854b787ba7d6045e8a8054731dc62430ae16c4bf08147539b1b6ef8f9361105d918b918110610f8857fe5b60408051938452602084019290925282820152519081900360600190a360035461108f9061271063ffffffff6110a116565b60035550505050505050505050565b50565b6000828201838110156110b357600080fd5b9392505050565b600080838311156110ca57600080fd5b5050900390565b6110d96116a3565b815160008115156110ff576040805180820190915260008082526020820152925061111d565b60208401905060408051908101604052808281526020018381525092505b5050919050565b606060006111306116ba565b600061113b85611344565b151561114657600080fd5b61114f85611376565b92508260405190808252806020026020018201604052801561118b57816020015b6111786116a3565b8152602001906001900390816111705790505b509350611197856113e6565b91505b6111a38261141f565b156111d1576111b18261143e565b84828151811015156111bf57fe5b6020908102909101015260010161119a565b505050919050565b60606000806111e784611480565b15156111f257600080fd5b6111fb846114a9565b91509150806040519080825280601f01601f19166020018201604052801561122d578160200160208202803883390190505b50925061111d828483611528565b60008060008061124a85611480565b151561125557600080fd5b61125e856114a9565b90935091506001821461127057600080fd5b50505160001a7f01000000000000000000000000000000000000000000000000000000000000000292915050565b60008060006112ac84611480565b15156112b757600080fd5b6112c0846114a9565b909250905060208111156112d357600080fd5b806020036101000a82510492505050919050565b60008060006112f584611480565b151561130057600080fd5b611309846114a9565b90925090506014811461131b57600080fd5b50516c01000000000000000000000000900492915050565b600061133e8261129e565b92915050565b60008082602001516000141561135d5760009150611370565b8260000151905060c0815160001a101591505b50919050565b60008060008060008061138887611344565b151561139757600095506113dc565b8651805160001a955093506113ab87611568565b840192506001876020015185010391505b8183116113d8576113cc836115e8565b909201916001016113bc565b8095505b5050505050919050565b6113ee6116ba565b60006113f983611344565b151561140457600080fd5b61140d83611568565b83519383529092016020820152919050565b60006114296116a3565b50508051602080820151915192015191011190565b6114466116a3565b6000806114528461141f565b156101065783602001519150611467826115e8565b828452602080850182905283820190860152905061111d565b6000808260200151600014156114995760009150611370565b5050515160c060009190911a1090565b60008060008060006114ba86611480565b15156114c557600080fd5b8551805160001a9350915060808310156114e757909350600192508390611520565b60b88310156115055760018660200151039350816001019450611520565b60b78303905080600187602001510303935080820160010194505b505050915091565b60006020601f83010484602085015b82841461155557602084028281015190820152600190930192611537565b6000865160200187015250505050505050565b6000806000836020015160001415611583576000925061111d565b50508151805160001a90608082101561159f576000925061111d565b60b88210806115ba575060c082101580156115ba575060f882105b156115c8576001925061111d565b60c08210156115dd5760b5198201925061111d565b5060f5190192915050565b8051600090811a60808110156116015760019150611370565b60b881101561161657607e1981019150611370565b60c081101561163f57600183015160b76020839003016101000a9004810160b519019150611370565b60f88110156116545760be1981019150611370565b6001929092015160f76020849003016101000a900490910160f51901919050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290565b604080518082019091526000808252602082015290565b6060604051908101604052806116ce6116a3565b81526020016000815250905600a165627a7a72305820be282b3b5bcf96c4d76ef3f77ad8b9178236758bea45d8c836acdcbbb8d69f130029",
"linkReferences": {},
"name": "",
"inputs": "(address)",
"type": "constructor",
"from": "account{0}"
}
}
],
"abis": {
"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470": [
{
"constant": true,
"inputs": [
{
"name": "b",
"type": "bytes"
}
],
"name": "toBytes32",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_preBytes",
"type": "bytes"
},
{
"name": "_postBytes",
"type": "bytes"
}
],
"name": "concat",
"outputs": [
{
"name": "",
"type": "bytes"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "x",
"type": "bytes32"
}
],
"name": "fromBytes32",
"outputs": [
{
"name": "",
"type": "bytes"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_bytes",
"type": "bytes"
},
{
"name": "_start",
"type": "uint256"
}
],
"name": "toUint",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "b",
"type": "bytes"
}
],
"name": "toBytes4",
"outputs": [
{
"name": "result",
"type": "bytes4"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_bytes",
"type": "bytes"
},
{
"name": "_start",
"type": "uint256"
},
{
"name": "_length",
"type": "uint256"
}
],
"name": "slice",
"outputs": [
{
"name": "",
"type": "bytes"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_num",
"type": "uint256"
}
],
"name": "fromUint",
"outputs": [
{
"name": "_ret",
"type": "bytes"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_bytes",
"type": "bytes"
}
],
"name": "leftPad",
"outputs": [
{
"name": "",
"type": "bytes"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_bytes",
"type": "bytes"
},
{
"name": "_start",
"type": "uint256"
}
],
"name": "toAddress",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
}
],
"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a471": [
{
"constant": true,
"inputs": [
{
"name": "hash",
"type": "bytes32"
},
{
"name": "sig",
"type": "bytes"
},
{
"name": "signer",
"type": "address"
}
],
"name": "ecverify",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "hash",
"type": "bytes32"
},
{
"name": "sig",
"type": "bytes"
}
],
"name": "ecrecovery",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "hash",
"type": "bytes32"
},
{
"name": "v",
"type": "uint8"
},
{
"name": "r",
"type": "bytes32"
},
{
"name": "s",
"type": "bytes32"
}
],
"name": "ecrecovery",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "data",
"type": "bytes"
},
{
"name": "sig",
"type": "bytes"
}
],
"name": "ecrecoveryFromData",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
}
],
"0xdaa77426c30c02a43d9fba4e841a6556c524d47030762eb14dc4af897e605d9b": [
{
"constant": true,
"inputs": [],
"name": "getCurrentValidatorSet",
"outputs": [
{
"name": "",
"type": "address[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "vote",
"type": "bytes"
},
{
"name": "sigs",
"type": "bytes"
}
],
"name": "checkSignatures2",
"outputs": [
{
"name": "",
"type": "uint256"
},
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "WITHDRAWAL_DELAY",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "unstakeClaim",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "newThreshold",
"type": "uint256"
}
],
"name": "updateValidatorThreshold",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "MIN_DEPOSIT_SIZE",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "unstake",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "finalizeCommit",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "user",
"type": "address"
},
{
"name": "exitEpoch",
"type": "uint256"
}
],
"name": "unstakeFor",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "addr",
"type": "address"
}
],
"name": "totalStakedFor",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "validatorThreshold",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "validatorState",
"outputs": [
{
"name": "amount",
"type": "int256"
},
{
"name": "stakerCount",
"type": "int256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "supportsHistory",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "dynasty",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "currentEpoch",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "currentValidatorSetSize",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalStaked",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "user",
"type": "address"
}
],
"name": "getStakerDetails",
"outputs": [
{
"name": "",
"type": "uint256"
},
{
"name": "",
"type": "uint256"
},
{
"name": "",
"type": "uint256"
},
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "stakers",
"outputs": [
{
"name": "epoch",
"type": "uint256"
},
{
"name": "amount",
"type": "uint256"
},
{
"name": "activationEpoch",
"type": "uint256"
},
{
"name": "deactivationEpoch",
"type": "uint256"
},
{
"name": "signer",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "epochs",
"type": "uint256"
}
],
"name": "updateMinLockInPeriod",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "currentValidatorSetTotalStake",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "user",
"type": "address"
},
{
"name": "unstakeValidator",
"type": "address"
},
{
"name": "signer",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
},
{
"name": "startEpoch",
"type": "uint256"
}
],
"name": "stakeForWithStartEpoch",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "minLockInPeriod",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "vote",
"type": "bytes"
},
{
"name": "sigs",
"type": "bytes"
}
],
"name": "checkSignatures3",
"outputs": [
{
"name": "",
"type": "address[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_signer",
"type": "address"
}
],
"name": "updateSigner",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "EPOCH_LENGTH",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "signerToStaker",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "user",
"type": "address"
},
{
"name": "unstakeValidator",
"type": "address"
},
{
"name": "signer",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"name": "stakeFor",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "maxStakeDrop",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "unstakeValidator",
"type": "address"
},
{
"name": "signer",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"name": "stake",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "newDynasty",
"type": "uint256"
}
],
"name": "updateDynastyValue",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "voteHash",
"type": "bytes32"
},
{
"name": "sigs",
"type": "bytes"
}
],
"name": "checkSignatures",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "user",
"type": "address"
}
],
"name": "isValidator",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"name": "_token",
"type": "address"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "newThreshold",
"type": "uint256"
},
{
"indexed": false,
"name": "oldThreshold",
"type": "uint256"
}
],
"name": "ThresholdChange",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "newDynasty",
"type": "uint256"
},
{
"indexed": false,
"name": "oldDynasty",
"type": "uint256"
}
],
"name": "DynastyValueChange",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "user",
"type": "address"
},
{
"indexed": true,
"name": "amount",
"type": "uint256"
},
{
"indexed": true,
"name": "deactivationEpoch",
"type": "uint256"
}
],
"name": "UnstakeInit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "validator",
"type": "address"
},
{
"indexed": true,
"name": "newSigner",
"type": "address"
},
{
"indexed": true,
"name": "oldSigner",
"type": "address"
}
],
"name": "SignerChange",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "user",
"type": "address"
},
{
"indexed": true,
"name": "signer",
"type": "address"
},
{
"indexed": true,
"name": "activatonEpoch",
"type": "uint256"
},
{
"indexed": false,
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"name": "total",
"type": "uint256"
}
],
"name": "Staked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "user",
"type": "address"
},
{
"indexed": false,
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"name": "total",
"type": "uint256"
}
],
"name": "Unstaked",
"type": "event"
}
],
"0x5a657105c493a1213c976c653e929218bb4a516bca307dce5861ec23fffa4e58": [
{
"constant": false,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "finalizeCommit",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "c",
"type": "string"
}
],
"name": "setChain",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "start",
"type": "uint256"
},
{
"name": "end",
"type": "uint256"
}
],
"name": "setFakeHeaderBlock",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_stakeManager",
"type": "address"
}
],
"name": "setStakeManager",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "slash",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "vote",
"type": "bytes"
},
{
"name": "sigs",
"type": "bytes"
},
{
"name": "extradata",
"type": "bytes"
}
],
"name": "submitHeaderBlock",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_token",
"type": "address"
},
{
"name": "_user",
"type": "address"
},
{
"name": "_amount",
"type": "uint256"
},
{
"name": "isWeth",
"type": "bool"
}
],
"name": "transferAmount",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"name": "_stakeManager",
"type": "address"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "proposer",
"type": "address"
},
{
"indexed": true,
"name": "number",
"type": "uint256"
},
{
"indexed": false,
"name": "start",
"type": "uint256"
},
{
"indexed": false,
"name": "end",
"type": "uint256"
},
{
"indexed": false,
"name": "root",
"type": "bytes32"
}
],
"name": "NewHeaderBlock",
"type": "event"
},
{
"constant": true,
"inputs": [],
"name": "chain",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "CHILD_BLOCK_INTERVAL",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "childChainContract",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "currentChildBlock",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "currentHeaderBlock",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_depositCount",
"type": "uint256"
}
],
"name": "depositBlock",
"outputs": [
{
"name": "_header",
"type": "uint256"
},
{
"name": "_owner",
"type": "address"
},
{
"name": "_token",
"type": "address"
},
{
"name": "_amount",
"type": "uint256"
},
{
"name": "_createdAt",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_headerNumber",
"type": "uint256"
}
],
"name": "headerBlock",
"outputs": [
{
"name": "_root",
"type": "bytes32"
},
{
"name": "_start",
"type": "uint256"
},
{
"name": "_end",
"type": "uint256"
},
{
"name": "_createdAt",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "headerBlocks",
"outputs": [
{
"name": "root",
"type": "bytes32"
},
{
"name": "start",
"type": "uint256"
},
{
"name": "end",
"type": "uint256"
},
{
"name": "createdAt",
"type": "uint256"
},
{
"name": "proposer",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "networkId",
"outputs": [
{
"name": "",
"type": "bytes"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "roundType",
"outputs": [
{
"name": "",
"type": "bytes32"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "stakeManager",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "voteType",
"outputs": [
{
"name": "",
"type": "bytes1"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]
}
}
{
"accounts": {
"account{0}": "0x0cdf0edd304a8e1715d5043d0afe3d3322cc6e3b"
},
"linkReferences": {},
"transactions": [
{
"timestamp": 1544858706819,
"record": {
"value": "0",
"abi": "0x96e2012ae1835f1b97d8521c4558a877b98f5dbd5fbe082f6a7747eaa649fe09",
"parameters": [
"0x0cdf0edd304a8e1715d5043d0afe3d3322cc6e3b",
"0x0000000000000000000000000000000000000000",
"0x0cdf0edd304a8e1715d5043d0afe3d3322cc6e3b",
"1000000000000000000"
],
"to": "0x77732829ad18d73a558e3ad8e4a28a6fa87f9cc2",
"name": "stakeFor",
"inputs": "(address,address,address,uint256)",
"type": "function",
"from": "account{0}"
}
},
{
"timestamp": 1544858715899,
"record": {
"value": "0",
"abi": "0x96e2012ae1835f1b97d8521c4558a877b98f5dbd5fbe082f6a7747eaa649fe09",
"parameters": [
"0xcd35d54eda5c9fd97768d16127f261c5d3f1aaeb",
"0x0000000000000000000000000000000000000000",
"0xcd35d54eda5c9fd97768d16127f261c5d3f1aaeb",
"1000000000000000000"
],
"to": "0x77732829ad18d73a558e3ad8e4a28a6fa87f9cc2",
"name": "stakeFor",
"inputs": "(address,address,address,uint256)",
"type": "function",
"from": "account{0}"
}
},
{
"timestamp": 1544858721770,
"record": {
"value": "0",
"abi": "0x96e2012ae1835f1b97d8521c4558a877b98f5dbd5fbe082f6a7747eaa649fe09",
"parameters": [
"0x115b164bf089c9490c192cc0fa6962af9e5f1202",
"0x0000000000000000000000000000000000000000",
"0x115b164bf089c9490c192cc0fa6962af9e5f1202",
"1000000000000000000"
],
"to": "0x77732829ad18d73a558e3ad8e4a28a6fa87f9cc2",
"name": "stakeFor",
"inputs": "(address,address,address,uint256)",
"type": "function",
"from": "account{0}"
}
},
{
"timestamp": 1544858728049,
"record": {
"value": "0",
"abi": "0x96e2012ae1835f1b97d8521c4558a877b98f5dbd5fbe082f6a7747eaa649fe09",
"parameters": [
"0x308ce5531beecb238bad497f485560c06a9e499f",
"0x0000000000000000000000000000000000000000",
"0x308ce5531beecb238bad497f485560c06a9e499f",
"1000000000000000000"
],
"to": "0x77732829ad18d73a558e3ad8e4a28a6fa87f9cc2",
"name": "stakeFor",
"inputs": "(address,address,address,uint256)",
"type": "function",
"from": "account{0}"
}
}
],
"abis": {
"0x96e2012ae1835f1b97d8521c4558a877b98f5dbd5fbe082f6a7747eaa649fe09": [
{
"constant": false,
"inputs": [],
"name": "finalizeCommit",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "unstakeValidator",
"type": "address"
},
{
"name": "signer",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"name": "stake",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "user",
"type": "address"
},
{
"name": "unstakeValidator",
"type": "address"
},
{
"name": "signer",
"type": "address"
},
{
"name": "amount",
"type": "uint256"
}
],
"name": "stakeFor",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "unstake",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [],
"name": "unstakeClaim",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "user",
"type": "address"
}
],
"name": "unstakeFor",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "newDynasty",
"type": "uint256"
}
],
"name": "updateDynastyValue",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "epochs",
"type": "uint256"
}
],
"name": "updateMinLockInPeriod",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_signer",
"type": "address"
}
],
"name": "updateSigner",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "newThreshold",
"type": "uint256"
}
],
"name": "updateValidatorThreshold",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"name": "_token",
"type": "address"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "newThreshold",
"type": "uint256"
},
{
"indexed": false,
"name": "oldThreshold",
"type": "uint256"
}
],
"name": "ThresholdChange",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"name": "newDynasty",
"type": "uint256"
},
{
"indexed": false,
"name": "oldDynasty",
"type": "uint256"
}
],
"name": "DynastyValueChange",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "user",
"type": "address"
},
{
"indexed": true,
"name": "amount",
"type": "uint256"
},
{
"indexed": true,
"name": "deactivationEpoch",
"type": "uint256"
}
],
"name": "UnstakeInit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "validator",
"type": "address"
},
{
"indexed": true,
"name": "newSigner",
"type": "address"
},
{
"indexed": true,
"name": "oldSigner",
"type": "address"
}
],
"name": "SignerChange",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "user",
"type": "address"
},
{
"indexed": true,
"name": "signer",
"type": "address"
},
{
"indexed": true,
"name": "activatonEpoch",
"type": "uint256"
},
{
"indexed": false,
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"name": "total",
"type": "uint256"
}
],
"name": "Staked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "user",
"type": "address"
},
{
"indexed": false,
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"name": "total",
"type": "uint256"
}
],
"name": "Unstaked",
"type": "event"
},
{
"constant": true,
"inputs": [
{
"name": "voteHash",
"type": "bytes32"
},
{
"name": "sigs",
"type": "bytes"
}
],
"name": "checkSignatures",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "currentEpoch",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "currentValidatorSetSize",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "currentValidatorSetTotalStake",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "dynasty",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "EPOCH_LENGTH",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getCurrentValidatorSet",
"outputs": [
{
"name": "",
"type": "address[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "user",
"type": "address"
}
],
"name": "getStakerDetails",
"outputs": [
{
"name": "",
"type": "uint256"
},
{
"name": "",
"type": "uint256"
},
{
"name": "",
"type": "uint256"
},
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "user",
"type": "address"
}
],
"name": "isValidator",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "maxStakeDrop",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "MIN_DEPOSIT_SIZE",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "minLockInPeriod",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "signerToStaker",
"outputs": [
{
"name": "",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "address"
}
],
"name": "stakers",
"outputs": [
{
"name": "epoch",
"type": "uint256"
},
{
"name": "amount",
"type": "uint256"
},
{
"name": "activationEpoch",
"type": "uint256"
},
{
"name": "deactivationEpoch",
"type": "uint256"
},
{
"name": "signer",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "supportsHistory",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "pure",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalStaked",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "addr",
"type": "address"
}
],
"name": "totalStakedFor",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "",
"type": "uint256"
}
],
"name": "validatorState",
"outputs": [
{
"name": "amount",
"type": "int256"
},
{
"name": "stakerCount",
"type": "int256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "validatorThreshold",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "WITHDRAWAL_DELAY",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
]
}
}
/* solium-disable */
pragma solidity ^0.4.24;
contract SizeTest {
// uint256 public constant s = 12;
function s() public constant returns (uint256) {
return 12;
}
}
pragma solidity ^0.4.24;
import { SafeMath } from "./SafeMath.sol";
import {RLP} from "./RLP.sol";
import { RLPEncode } from "./RLPEncode.sol";
import { BytesLib } from "./BytesLib.sol";
import { ECVerify } from "./ECVerify.sol";
import { AvlTree } from "./AvlTree.sol";
import { StakeManagerInterface } from "./StakeManagerInterface.sol";
import { Math } from "./Math.sol";
contract StakeManager is StakeManagerInterface {
using SafeMath for uint256;
using SafeMath for uint128;
using ECVerify for bytes32;
uint96 MAX_UINT96 = (2**96)-1; //Todo: replace with erc20 token max value
// ERC20 public token;
event ThresholdChange(uint256 newThreshold, uint256 oldThreshold);
event DynastyValueChange(uint256 newDynasty, uint256 oldDynasty);
// optional event to ack unstaking
event UnstakeInit(address indexed user, uint256 indexed amount, uint256 indexed deactivationEpoch);
// signer changed
event SignerChange(address indexed validator, address indexed newSigner, address indexed oldSigner);
// genesis/governance variables
uint256 public dynasty = 2**13; // unit: epoch
uint256 public MIN_DEPOSIT_SIZE = (10**18); // in ERC20 token
uint256 public EPOCH_LENGTH = 256; // unit : block
uint256 public WITHDRAWAL_DELAY = dynasty.div(2); // unit: epoch
uint256 public validatorThreshold = 10;
uint256 public maxStakeDrop = 95; // in percent 100-x, current is 5%
uint256 public minLockInPeriod = 2; // unit: dynasty
uint256 public totalStaked = 0;
uint256 public currentEpoch = 1;
AvlTree validatorList;
struct Staker {
uint256 epoch;
uint256 amount;
uint256 activationEpoch;
uint256 deactivationEpoch;
address signer;
}
// signer to Staker mapping
mapping (address => address) public signerToStaker;
mapping (address => Staker) public stakers;
struct State {
int256 amount;
int256 stakerCount;
}
//Mapping for epoch to totalStake for that epoch
mapping (uint256 => State) public validatorState;
constructor (address _token) public {
require(_token != address(0x0));
// token = ERC20(_token);
validatorList = new AvlTree(); // TODO: bind with stakemanager
}
// only staker
modifier onlyStaker() {
require(totalStakedFor(msg.sender) > 0);
_;
}
function stake(address unstakeValidator, address signer, uint256 amount) public {
stakeFor(msg.sender, unstakeValidator, signer, amount);
}
function stakeFor(address user, address unstakeValidator, address signer, uint256 amount) public {
require(stakers[user].epoch == 0, "No second time staking");
// currentValidatorSetSize*2 means everyone is commited
require(validatorThreshold*2 > validatorList.currentSize(), "Validator set full");
require(amount < MAX_UINT96, "Stay realistic!!");
require(signer != address(0x0) && signerToStaker[signer] == address(0x0));
uint256 minValue = validatorList.getMin();
if (minValue != 0) {
minValue = minValue >> 160;
minValue = minValue.mul(maxStakeDrop).div(100);
}
minValue = Math.max(minValue, MIN_DEPOSIT_SIZE);
require(amount >= minValue, "Stake should be gt then X% of current lowest");
// require(token.transferFrom(msg.sender, address(this), amount), "Transfer stake");
totalStaked = totalStaked.add(amount);
stakers[user] = Staker({
epoch: currentEpoch,
amount: amount,
activationEpoch: 0,
deactivationEpoch: 0,
signer: signer
});
signerToStaker[signer] = user;
// 96bits amount(10^29) 160 bits user address
uint256 value = amount << 160 | uint160(user);
validatorList.insert(value);
// for empty slot address(0x0) is validator
if (uint256(validatorState[currentEpoch].stakerCount) < validatorThreshold) {
stakers[user].activationEpoch = currentEpoch;
validatorState[currentEpoch].amount += int256(amount);
validatorState[currentEpoch].stakerCount += int256(1);
} else {
require(stakers[unstakeValidator].epoch != 0);
require(stakers[unstakeValidator].activationEpoch != 0 && stakers[unstakeValidator].deactivationEpoch == 0);
require(stakers[user].amount > stakers[unstakeValidator].amount);
value = stakers[unstakeValidator].amount << 160 | uint160(unstakeValidator);
uint256 dPlusTwo = currentEpoch.add(dynasty.mul(2));
stakers[unstakeValidator].deactivationEpoch = dPlusTwo;
stakers[user].activationEpoch = dPlusTwo;
validatorState[dPlusTwo].amount = (
validatorState[dPlusTwo].amount +
int256(amount) - int256(stakers[unstakeValidator].amount)
);
emit UnstakeInit(unstakeValidator, stakers[unstakeValidator].amount, dPlusTwo);
}
emit Staked(user, signer, stakers[user].activationEpoch, amount, totalStaked);
}
// set fake start epoch
function stakeForWithStartEpoch(address user, address unstakeValidator, address signer, uint256 amount, uint256 startEpoch) public {
require(stakers[user].epoch == 0, "No second time staking");
// currentValidatorSetSize*2 means everyone is commited
require(validatorThreshold*2 > validatorList.currentSize(), "Validator set full");
require(amount < MAX_UINT96, "Stay realistic!!");
require(signer != address(0x0) && signerToStaker[signer] == address(0x0), "Already present");
uint256 minValue = validatorList.getMin();
if (minValue != 0) {
minValue = minValue >> 160;
minValue = minValue.mul(maxStakeDrop).div(100);
}
minValue = Math.max(minValue, MIN_DEPOSIT_SIZE);
require(amount >= minValue, "Stake should be gt then X% of current lowest");
// require(token.transferFrom(msg.sender, address(this), amount), "Transfer stake");
totalStaked = totalStaked.add(amount);
stakers[user] = Staker({
epoch: currentEpoch,
amount: amount,
activationEpoch: 0,
deactivationEpoch: 0,
signer: signer
});
signerToStaker[signer] = user;
// 96bits amount(10^29) 160 bits user address
uint256 value = amount << 160 | uint160(user);
validatorList.insert(value);
uint256 dPlusTwo = startEpoch;
stakers[unstakeValidator].deactivationEpoch = dPlusTwo;
stakers[user].activationEpoch = dPlusTwo;
validatorState[dPlusTwo].amount = (
validatorState[dPlusTwo].amount +
int256(amount) - int256(stakers[unstakeValidator].amount)
);
validatorState[dPlusTwo].stakerCount += int256(1);
emit Staked(user, signer, stakers[user].activationEpoch, amount, totalStaked);
}
function unstake() public onlyStaker {
unstakeFor(msg.sender, currentEpoch.add(dynasty.mul(2)));
}
function unstakeFor(address user, uint256 exitEpoch) public {
require(stakers[user].activationEpoch > 0 && stakers[user].deactivationEpoch == 0);
uint256 amount = stakers[user].amount;
stakers[user].deactivationEpoch = exitEpoch;
//update future
validatorState[exitEpoch].amount = (
validatorState[exitEpoch].amount - int256(amount));
validatorState[exitEpoch].stakerCount = (
validatorState[exitEpoch].stakerCount - 1);
emit UnstakeInit(user, amount, exitEpoch);
}
function unstakeClaim() public onlyStaker {
// can only claim stake back after WITHDRAWAL_DELAY
require(stakers[msg.sender].deactivationEpoch.add(WITHDRAWAL_DELAY) <= currentEpoch);
uint256 amount = stakers[msg.sender].amount;
totalStaked = totalStaked.sub(amount);
validatorList.deleteNode(amount << 160 | uint160(msg.sender));
// TODO :add slashing here use soft slashing in slash amt variable
delete signerToStaker[stakers[msg.sender].signer];
delete stakers[msg.sender];
// require(token.transfer(msg.sender, amount));
emit Unstaked(msg.sender, amount, totalStaked);
}
// returns valid validator for current epoch
function getCurrentValidatorSet() public view returns (address[] memory) {
address[] memory _validators = validatorList.getTree();
for (uint256 i = 0;i < _validators.length;i++) {
if (!isValidator(_validators[i])) {
delete _validators[i];
}
}
return _validators;
}
function getStakerDetails(address user) public view returns(uint256, uint256, uint256, address) {
return (
stakers[user].amount,
stakers[user].activationEpoch,
stakers[user].deactivationEpoch,
stakers[user].signer
);
}
function totalStakedFor(address addr) public view returns (uint256) {
require(addr != address(0x0));
return stakers[addr].amount;
}
function supportsHistory() public pure returns (bool) {
return false;
}
// Change the number of validators required to allow a passed header root
function updateValidatorThreshold(uint256 newThreshold) public {
require(newThreshold > 0);
emit ThresholdChange(newThreshold, validatorThreshold);
validatorThreshold = newThreshold;
}
function updateDynastyValue(uint256 newDynasty) public {
require(newDynasty > 0);
emit DynastyValueChange(newDynasty, dynasty);
dynasty = newDynasty;
}
function updateSigner(address _signer) public onlyStaker {
require(_signer != address(0x0) && signerToStaker[_signer] == address(0x0));
// update signer event
emit SignerChange(msg.sender, stakers[msg.sender].signer, _signer);
delete signerToStaker[stakers[msg.sender].signer];
signerToStaker[_signer] = msg.sender;
stakers[msg.sender].signer = _signer;
}
function finalizeCommit() public {
uint256 nextEpoch = currentEpoch.add(1);
// update totalstake and validator count
validatorState[nextEpoch].amount = (
validatorState[currentEpoch].amount + validatorState[nextEpoch].amount
);
validatorState[nextEpoch].stakerCount = (
validatorState[currentEpoch].stakerCount + validatorState[nextEpoch].stakerCount
);
currentEpoch = nextEpoch;
// erase old data/history
delete validatorState[currentEpoch.sub(1)];
}
function updateMinLockInPeriod(uint256 epochs) public {
minLockInPeriod = epochs;
}
function currentValidatorSetSize() public view returns (uint256) {
return uint256(validatorState[currentEpoch].stakerCount);
}
function currentValidatorSetTotalStake() public view returns (uint256) {
return uint256(validatorState[currentEpoch].amount);
}
function isValidator(address user) public view returns (bool) {
return (
stakers[user].amount > 0 &&
stakers[user].activationEpoch <= currentEpoch &&
(stakers[user].deactivationEpoch == 0 ||
stakers[user].deactivationEpoch >= currentEpoch)
);
}
function checkSignatures (
bytes32 voteHash,
bytes memory sigs
) public view returns (bool) {
// total voting power
uint256 stakePower = 0;
address user;
address lastAdd = address(0x0); // cannot have address(0x0) as an owner
for (uint64 i = 0; i < sigs.length; i += 65) {
bytes memory sigElement = BytesLib.slice(sigs, i, 65);
address signer = voteHash.ecrecovery(sigElement);
user = signerToStaker[signer];
// check if signer is stacker and not proposer
if (
isValidator(user) &&
signer > lastAdd
) {
lastAdd = signer;
stakePower = stakePower.add(stakers[user].amount);
} else {
break;
}
}
return stakePower >= currentValidatorSetTotalStake().mul(2).div(3).add(1);
}
function checkSignatures2 (
bytes vote,
bytes memory sigs
) public view returns (uint256, uint256) {
bytes32 voteHash = keccak256(vote);
// total voting power
uint256 stakePower = 0;
address user;
address lastAdd = address(0x0); // cannot have address(0x0) as an owner
for (uint64 i = 0; i < sigs.length; i += 65) {
bytes memory sigElement = BytesLib.slice(sigs, i, 65);
address signer = voteHash.ecrecovery(sigElement);
user = signerToStaker[signer];
// check if signer is stacker and not proposer
if (
isValidator(user) &&
signer > lastAdd
) {
lastAdd = signer;
stakePower = stakePower.add(stakers[user].amount);
} else {
break;
}
}
return (stakePower, currentValidatorSetTotalStake());
}
function checkSignatures3 (
bytes vote,
bytes memory sigs
) public view returns (address[]) {
bytes32 voteHash = keccak256(vote);
address[] memory d = new address[]((sigs.length / 65) + 1);
address lastAdd = address(0x0); // cannot have address(0x0) as an owner
for (uint64 i = 0; i < sigs.length; i += 65) {
bytes memory sigElement = BytesLib.slice(sigs, i, 65);
address signer = voteHash.ecrecovery(sigElement);
// check if signer is stacker and not proposer
if (
signer > lastAdd
) {
lastAdd = signer;
d[i / 65] = signer;
} else {
break;
}
}
return d;
}
}
pragma solidity ^0.4.24;
// ERC900
interface StakeManagerInterface {
event Staked(address indexed user, address indexed signer, uint256 indexed activatonEpoch, uint256 amount, uint256 total);
event Unstaked(address indexed user, uint256 amount, uint256 total);
function stake(address unstakeValidator, address signer, uint256 amount) external;
function stakeFor(address user, address unstakeValidator, address signer, uint256 amount) external;
function unstake() external;
function totalStakedFor(address addr) external view returns (uint256);
// function totalStaked() public view returns (uint256);
// function token() public view returns (address);
function supportsHistory() external pure returns (bool);
// optional
// function lastStakedFor(address addr) public view returns (uint256);
// function totalStakedForAt(address addr, uint256 blockNumber) public view returns (uint256);
// function totalStakedAt(uint256 blockNumber) public view returns (uint256);
}
// Library for RLP encoding a list of bytes arrays.
// Modeled after ethereumjs/rlp (https://github.com/ethereumjs/rlp)
// [Very] modified version of Sam Mayo's library.
pragma solidity ^0.4.24;
contract Validate {
function checkAddress(bytes pubkey) view returns (address) {
return address(keccak256(pubkey));
}
// 0x04cdc503fdbb89fe6b92c747fb044622fa63563faf73bc734ea23c20b190259173a614c0ecb6ba7507d8e13e558a86eccc6ce84f15fae27e4c9119528c5fac1483
}
pragma solidity ^0.4.24;
import { SafeMath } from "./SafeMath.sol";
import { RLP } from "./RLP.sol";
import { RLPEncode } from "./RLPEncode.sol";
import { BytesLib } from "./BytesLib.sol";
import "./ECVerify.sol";
contract ValidatorSet {
using SafeMath for uint256;
using SafeMath for uint8;
// using BytesLib for bytes32;
int256 constant INT256_MIN = -int256((2**255)-1);
uint256 constant UINT256_MAX = (2**256)-1;
using RLP for bytes;
using RLP for RLP.RLPItem;
using RLP for RLP.Iterator;
event NewProposer(address indexed user, bytes data);
struct Validator {
uint256 votingPower;
address validator;
string pubkey;
}
uint256 public startBlock;
uint256 public endBlock;
Validator[] public validators;
function addValidator(address validator, uint256 votingPower, string _pubkey) public {
validators.push(Validator(votingPower, validator,_pubkey)); //use index instead
}
function getPubkey(uint256 index) public view returns(string){
// return BytesLib.concat(abi.encodePacked(validators[index].pubkey1), abi.encodePacked(validators[index].pubkey2));
return validators[index].pubkey;
}
function removeValidator(uint256 _index){
delete validators[_index];
}
function getValidatorSet() public view returns (uint256[] ,address[]){
uint256[] memory powers= new uint256[](validators.length);
address[] memory validatorAddresses= new address[](validators.length);
for (uint8 i = 0; i < validators.length; i++) {
validatorAddresses[i]=validators[i].validator;
powers[i]=validators[i].votingPower;
}
return (powers,validatorAddresses);
}
// Inputs: start,end,roothash,vote bytes,signatures of validators ,tx(extradata)
// Constants: chainid,type,votetype
// extradata => start,end ,proposer etc rlp encoded hash
//
//
// bytes32 public chain = keccak256("test-chain-E5igIA");
bytes32 public chain = keccak256("test-chain-y1aqmb");
bytes32 public constant roundType = keccak256("vote");
byte public constant voteType = 0x02;
// @params start-> startBlock , end-> EndBlock , roothash-> merkelRoot
function validate(bytes vote, bytes sigs, bytes extradata) public returns(uint, uint, bytes32) {
RLP.RLPItem[] memory dataList = vote.toRLPItem().toList();
require(keccak256(dataList[0].toData()) == chain, "Chain ID not same");
require(keccak256(dataList[1].toData()) == roundType, "Round type not same ");
require(dataList[4].toByte() == voteType, "Vote type not same");
// validate extra data using getSha256(extradata)
require(keccak256(dataList[6].toData())==keccak256(getSha256(extradata)), "extradata is not valid");
// check proposer
require(msg.sender==dataList[5].toAddress(), "Invalid msg sender");
// decode extra data and validate start,end etc
RLP.RLPItem[] memory txDataList;
txDataList=extradata.toRLPItem().toList()[0].toList();
// extract end and assign to current child
// require(txDataList[0].toUint() == startBlock, "Start block does not match");
// require(txDataList[1].toUint() == endBlock, "End block does not match");
startBlock = txDataList[0].toUint();
endBlock = txDataList[1].toUint();
bytes32 root = txDataList[2].toBytes32();
//slice sigs and do ecrecover from validator set
for (uint64 i = 0; i < sigs.length; i += 65) {
bytes memory sigElement = BytesLib.slice(sigs, i, 65);
address Lastsigner = ECVerify.ecrecoveryFromData(vote,sigElement);
}
// signer address , proposer address , end block
return (startBlock, endBlock, root);
}
function setStartBlock(uint256 _startBlock){
startBlock=_startBlock;
}
function getSha256(bytes input) public returns (bytes20) {
bytes32 hash = sha256(input);
return bytes20(hash);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment