gitpivot upgradability

This commit is contained in:
Ricardo Guilherme Schmidt
2017-11-22 21:14:38 -02:00
parent 32d744d71a
commit 286974b721
40 changed files with 825 additions and 458 deletions
+5 -9
View File
@@ -1,16 +1,12 @@
# GitHubOracle
# GitPivot
Ethereum application to incentive open-source development in GitHub by opening direct fair payment channels for bounties and indirect payments through tokenization of commits.
This project was formely known as GitHubTokens, created to tokenize contributions of [TheEtherian news platform](https://etherian.world/).
The project become embraced by [Status Network](status.im) that will integrate it as backend of a trustless [Commiteth](https://github.com/status-im/commiteth).
## System Features
### Configurable reward modes by project
For a project being accepted by GitHubOracle it must have a file in root of tree called `.gitpoints` with specifing `user-agent:` to `*` or `githuboracle`.
For a project being accepted by GitPivot it must have a file in root of tree called `.gitpoints` with specifing `user-agent:` to `*` or `GitPivot`.
Example:
@@ -26,8 +22,8 @@ reactions-reward: heart, +1
### GitHub User Ethereum Address
To control GitHubOracle users need to link their GitHub user login to an ethereum address.
User calls GitHubOracle and passes his username and the gistid, GitHubOracle registers users by loading gistid file called `register.txt` under user `login`. This file must contain only the ethereum address who made the register call, starting with `0x`.
To control GitPivot users need to link their GitHub user login to an ethereum address.
User calls GitPivot and passes his username and the gistid, GitPivot registers users by loading gistid file called `register.txt` under user `login`. This file must contain only the ethereum address who made the register call, starting with `0x`.
### Tokenize project merged contributions
@@ -43,7 +39,7 @@ Repositories that enabled tokenizations of contributions also have a DonationBan
### Reward bounties by contribuion in GitHub Issues.
Issues may be tracked by GitHubOracle, accept payments, depending on the `.gitpoints` configuration, positively reacted posts and merged pull requests/commits generate points that allow issue contributors to withdraw a fair share of balances related to the issue.
Issues may be tracked by GitPivot, accept payments, depending on the `.gitpoints` configuration, positively reacted posts and merged pull requests/commits generate points that allow issue contributors to withdraw a fair share of balances related to the issue.
## Network Features
-108
View File
@@ -1,108 +0,0 @@
pragma solidity ^0.4.11;
import "./common/Controlled.sol";
import "./common/oraclizeAPI_0.4.sol";
import "./common/strings.sol";
/**
* @title GitHubAPIReg.sol
* Abstract Logic for GitHubOracle Registries.
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract GitHubAPIReg is Controlled, usingOraclize {
using strings for string;
using strings for strings.slice;
string cred = "";
event OracleEvent(bytes32 myid, string result, bytes proof);
function GitHubAPIReg() {
oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
}
//owner management
function setAPICredentials(string _client_id, string _client_secret) public onlyController {
strings.slice[] memory cm = new strings.slice[](5);
cm[0] = strings.toSlice("?client_id=");
cm[1] = _client_id.toSlice();
cm[2] = strings.toSlice("&client_secret=");
cm[4] = _client_secret.toSlice();
cred = strings.toSlice("").join(cm);
}
function clearAPICredentials() public onlyController {
cred = "";
}
function getNextString(bytes _str, uint8 _pos) internal returns (string, uint8) {
uint8 start = 0;
uint8 end = 0;
uint strl =_str.length;
for (;strl > _pos; _pos++) {
if (_str[_pos] == "\"") { //Found quotation mark
if (_str[_pos-1] != "\\") { //is not escaped
end = start == 0 ? 0: _pos;
start = start == 0 ? (_pos+1) : start;
if(end > 0) {
break;
}
}
}
}
bytes memory str = new bytes(end-start);
for (_pos=0; _pos<str.length; _pos++) {
str[_pos] = _str[start+_pos];
}
for (_pos = end + 1; _pos < _str.length; _pos++) {
if (_str[_pos] == ',') {
_pos++;
break;
}
} //end
return (string(str), _pos);
}
function getNextUInt(bytes _str, uint8 _pos) internal returns (uint, uint8) {
uint val = 0;
uint strl =_str.length;
for (; strl > _pos; _pos++) {
byte bp = _str[_pos];
if (bp == ",") {//Find ends
_pos++; break;
} else if ((bp >= 48) && (bp <= 57)) { //only ASCII numbers
val *= 10;
val += uint(bp) - 48;
}
}
return (val, _pos);
}
function getNextAddr(bytes _str, uint8 _pos) internal returns (address, uint8) {
uint160 iaddr = 0;
uint strl =_str.length;
for (;strl > _pos; _pos++) {
byte bp = _str[_pos];
if (bp == "0") {
if (_str[_pos+1] == "x") {
for (_pos=_pos+2; _pos<2+2*20; _pos+=2) {
iaddr *= 256;
iaddr += (uint160(hexVal(uint160(_str[_pos])))*16+uint160(hexVal(uint160(_str[_pos+1]))));
}
_pos++;
break;
}
}else if (bp == ",") {
_pos++;
break;
}
}
return (address(iaddr), _pos);
}
function hexVal(uint val) internal returns (uint) {
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
}
+7 -14
View File
@@ -4,13 +4,13 @@ import "./common/Controlled.sol";
import "./PointsOracle.sol";
import "./UserOracle.sol";
import "./RepositoryOracle.sol";
import "./IGitPivot.sol";
/**
* @title GitPivot.sol
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract GitPivot is Controlled, DGitI {
contract GitPivot is Controlled, IGitPivot {
UserOracle public userOracle;
RepositoryOracle public repositoryOracle;
@@ -40,7 +40,7 @@ contract GitPivot is Controlled, DGitI {
function getRepository(string _repository, string _branch) public constant returns (uint repoId) {
repoId = repositoryOracle.getId(_repository);
require(repoId != 0);
require(repositoryOracle.getBranch(repoId) == keccak256(_branch));
require(repositoryOracle.branch(repoId) == keccak256(_branch));
}
function start(string _repository, string _branch, string _token) public payable {
@@ -96,7 +96,7 @@ contract GitPivot is Controlled, DGitI {
//claims pending points
function claimPending(uint _repoId, uint _userId) public {
GitRepositoryI repoaddr = GitRepositoryI(repositoryOracle.getAddr(_repoId));
GitRepository repoaddr = GitRepository(repositoryOracle.getAddr(_repoId));
uint total = pending[_userId][_repoId];
delete pending[_userId][_repoId];
require(repoaddr.claim(userOracle.getAddr(_userId), total));
@@ -126,13 +126,6 @@ contract GitPivot is Controlled, DGitI {
}
}
function upgrade(uint[] _repoIds) public onlyUpgrading onlyController {
uint len = _repoIds.length;
for (uint i = 0; i < len; i++) {
Controlled(repositoryOracle.getAddr(_repoIds[i])).changeController(newContract);
}
}
function pendingScan(uint256 _projectId, string _lastCommit, string _pendingTail) public package {
repositories[_projectId].pending[_pendingTail] = _lastCommit;
}
@@ -154,7 +147,7 @@ contract GitPivot is Controlled, DGitI {
public
package
{
GitRepositoryI repo = GitRepositoryI(repositoryOracle.getAddr(_projectId));
GitRepository repo = GitRepository(repositoryOracle.getAddr(_projectId));
repo.setBounty(_issueId, _state, _closedAt);
}
@@ -167,7 +160,7 @@ contract GitPivot is Controlled, DGitI {
public
package
{
GitRepositoryI repo = GitRepositoryI(repositoryOracle.getAddr(_projectId));
GitRepository repo = GitRepository(repositoryOracle.getAddr(_projectId));
uint len = _userId.length;
for (uint i = 0; i < len; i++) {
address addr = userOracle.getAddr(_userId[i]);
@@ -176,7 +169,7 @@ contract GitPivot is Controlled, DGitI {
}
function newPoints(uint _repoId, uint[] _userIds, uint[] _points) public package {
GitRepositoryI repo = GitRepositoryI(repositoryOracle.getAddr(_repoId));
GitRepository repo = GitRepository(repositoryOracle.getAddr(_repoId));
uint len = _userIds.length;
for (uint i = 0; i < len; i++) {
uint _userId = _userIds[i];
+57
View File
@@ -0,0 +1,57 @@
pragma solidity ^0.4.17;
import "./deploy/AbstractRecoverer.sol";
contract ENS {
function owner(bytes32 node) constant returns (address);
function resolver(bytes32 node) constant returns (Resolver);
function ttl(bytes32 node) constant returns (uint64);
function setOwner(bytes32 node, address owner);
function setSubnodeOwner(bytes32 node, bytes32 label, address owner);
function setResolver(bytes32 node, address resolver);
function setTTL(bytes32 node, uint64 ttl);
}
contract Resolver {
function addr(bytes32 node) constant returns (address);
}
/**
* @title GitPivotRecoverer
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Common Recoverer for GitPivot.
* address resolved from ens recover.gitpivot.eth can set new system.
*/
contract GitPivotRecoverer is BasicSystemStorage {
/**
* @dev will be callable in emergency state of RecorverableSystem
*/
function recoverSystem(address newSystem) public {
require(msg.sender == consensusContract());
system = newSystem;
}
/**
* @dev resolves recover.gitpivot.eth
*/
function consensusContract() public constant returns(address) {
bytes32 node = 0xa33a22622efdf12b4175a11fbc58ec45d4e93a0160952cc8e48867c5c50a3404; //recover.gitpivot.eth //bytes32 node = keccak256("recover", keccak256("gitpivot", keccak256("eth")));
address ensAddress = 0x314159265dD8dbb310642f98f50C066173C1259b;
if (codeSize(ensAddress) == 0) {
return 0x41CaB970f931F2EC3195C416B8Fa65e99814e7aF; //ensAddress = 0x112234455C3a32FD11230C42E7Bccd4A84e02010;
}
return ENS(ensAddress).resolver(node).addr(node);
}
function codeSize(address _addr) internal constant returns(uint size) {
if (_addr == 0) {
return 0;
}
assembly {
size := extcodesize(_addr)
}
}
}
+8 -17
View File
@@ -1,25 +1,16 @@
pragma solidity ^0.4.11;
import "./bank/CollaborationBank.sol";
import "./bank/BountyBank.sol";
import "./common/Controlled.sol";
contract GitRepositoryI is Controlled {
function claim(address _user, uint _total) returns (bool);
function setBounty(uint256 _issueId, bool _state, uint256 _closedAt);
function setBountyPoints(uint256 _issueId, address _claimer, uint256 _points);
}
import "./IGitRepository.sol";
/**
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract GitRepository is TokenController, GitRepositoryI {
contract GitRepository is IGitRepository, Controlled, TokenController {
MiniMeToken public token;
CollaborationBank public donationBank;
BountyBank public bountyBank;
string public name;
uint256 public uid;
@@ -27,7 +18,6 @@ contract GitRepository is TokenController, GitRepositoryI {
function GitRepository(uint256 _uid, string _name) {
uid = _uid;
name = _name;
bountyBank = new BountyBank();
}
function setDonationBank(MiniMeToken _token, uint _epochLenght) public onlyController {
@@ -44,14 +34,15 @@ contract GitRepository is TokenController, GitRepositoryI {
}
function setBounty(uint256 _issueId, bool _state, uint256 _closedAt) public onlyController {
if (_state)
bountyBank.open(_issueId);
else
bountyBank.close(_issueId, _closedAt);
if (_state) {
//TODO: open issue
} else {
//TODO: close issue
}
}
function setBountyPoints(uint256 _issueId, address _claimer, uint256 _points) public onlyController {
bountyBank.setClaimer(_issueId, _claimer, _points);
//TODO: set points
}
function proxyPayment(address) public payable returns(bool) {
+44
View File
@@ -0,0 +1,44 @@
/**
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract IGitPivot {
/**
*
*/
function setHead(uint256 projectId, string head) public;
/**
*
*/
function setTail(uint256 projectId, string tail) public;
/**
*
*/
function newPoints(uint256 projectId, uint256[] userIds, uint[] totals) public;
/**
*
*/
function pendingScan(uint256 projectId, string lastCommit, string pendingTail) public;
/**
*
*/
function setIssue(
uint256 projectId,
uint256 issueId,
bool state,
uint256 closedAt) public;
/**
*
*/
function setIssuePoints(
uint256 projectId,
uint256 issueId,
uint256[] userIds,
uint256[] points) public;
}
+8
View File
@@ -0,0 +1,8 @@
pragma solidity ^0.4.11;
contract IGitRepository {
function claim(address _user, uint _total) returns (bool);
function setBounty(uint256 _issueId, bool _state, uint256 _closedAt);
function setBountyPoints(uint256 _issueId, address _claimer, uint256 _points);
}
+110
View File
@@ -0,0 +1,110 @@
pragma solidity ^0.4.11;
import "./common/strings.sol";
/**
* @title JSONHelper
* Abstract Logic for JSON responses from Oracle
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract JSONHelper {
function getCredentialString(string _clientId, string _clientSecret) internal returns (string cred) {
strings.slice[] memory cm = new strings.slice[](4);
cm[0] = strings.toSlice("?client_id=");
cm[1] = strings.toSlice(_clientId);
cm[2] = strings.toSlice("&client_secret=");
cm[3] = strings.toSlice(_clientSecret);
cred = strings.join(cm);
}
function getNextString(bytes _str, uint256 _pos) internal pure returns (string str, uint256 next) {
var (start, end) = findStringBounds(_str, _pos);
str = string(copyBytesPart(_str, start, end));
next = findNextChar(_str, end, ",") + 1;
}
function getNextAddr(bytes _str, uint256 _pos) internal pure returns (address, uint256) {
uint160 iaddr = 0;
uint len = _str.length;
for (; len > _pos; _pos++) {
byte bp = _str[_pos];
if (bp == "0") {
if (_str[_pos+1] == "x") {
for (_pos = _pos+2; _pos < 2 + 2 * 20; _pos += 2) {
iaddr *= 256;
iaddr += (uint160(hexVal(uint160(_str[_pos])))*16+uint160(hexVal(uint160(_str[_pos+1]))));
}
_pos++;
break;
}
}else if (bp == ",") {
_pos++;
break;
}
}
return (address(iaddr), _pos);
}
function getNextUInt(bytes _str, uint256 _pos) internal pure returns (uint, uint256) {
uint val = 0;
uint len = _str.length;
for (; len > _pos; _pos++) {
byte bp = _str[_pos];
if (bp == ",") {//Find ends
_pos++;
break;
} else if ((bp >= 48) && (bp <= 57)) { //only ASCII numbers
val *= 10;
val += uint(bp) - 48;
}
}
return (val, _pos);
}
function hexVal(uint val) internal pure returns (uint) {
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
function copyBytesPart(bytes _src, uint256 _start, uint256 _end) private pure returns (bytes res) {
uint256 len = _end - _start;
res = new bytes(len);
for (uint i = 0; i < len; i++) {
res[i] = _src[_start + i];
}
}
/**
* @dev Finds next char. Retuns _str length case not found.
*/
function findNextChar(bytes _str, uint256 _start, byte _char) private pure returns(uint256 pos) {
uint256 len = _str.length;
for (pos = _start + 1; pos < len; pos++) {
if (_str[pos] == _char) {
return pos;
}
}
}
/**
* @dev Finds JSON string bounds: first unescaped " and next unescaped" . Returns 0,0 case not found.
* @param _str The converted to bytes string.
* @param _offset The search offset into _str
*/
function findStringBounds(bytes _str, uint256 _offset) private pure returns (uint256 start, uint256 end) {
uint256 len = _str.length;
for (uint256 _pos = _offset; _pos < len; _pos++) {
if (_str[_pos] == "\"") {
if (_pos == 0 || _str[_pos-1] != "\\") { //is not escaped
end = start == 0 ? 0 : _pos;
start = start == 0 ? (_pos+1) : start;
if (end > 0) {
return (start, end);
}
}
}
}
return (0, 0);
}
}
+2 -3
View File
@@ -1,12 +1,12 @@
pragma solidity ^0.4.4;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
if (msg.sender == owner)
_;
}
function Migrations() {
@@ -21,5 +21,4 @@ contract Migrations {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
+7 -108
View File
@@ -1,61 +1,17 @@
pragma solidity ^0.4.10;
import "./common/oraclizeAPI_0.4.sol";
import "./common/Controlled.sol";
import "./common/strings.sol";
import "./oraclize/oraclizeAPI_0.4.sol";
import "./JSONHelper.sol";
import "./IGitPivot.sol";
import "./deploy/KillableModel.sol";
/**
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract GitPivotI {
contract PointsOracle is KillableModel, Controlled, JSONHelper, usingOraclize {
/**
*
*/
function setHead(uint256 projectId, string head) public;
/**
*
*/
function setTail(uint256 projectId, string tail) public;
/**
*
*/
function newPoints(uint256 projectId, uint256[] userIds, uint[] totals) public;
/**
*
*/
function pendingScan(uint256 projectId, string lastCommit, string pendingTail) public;
/**
*
*/
function setIssue(
uint256 projectId,
uint256 issueId,
bool state,
uint256 closedAt) public;
/**
*
*/
function setIssuePoints(
uint256 projectId,
uint256 issueId,
uint256[] userIds,
uint256[] points) public;
}
/**
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract PointsOracle is Controlled, usingOraclize {
event OracleEvent(bytes32 myid, string result, bytes proof);
using strings for string;
using strings for strings.slice;
@@ -220,7 +176,6 @@ contract PointsOracle is Controlled, usingOraclize {
*
*/
function __callback(bytes32 myid, string result, bytes proof) public {
OracleEvent(myid, result, proof);
require (msg.sender == oraclize.cbAddress());
processRequest(bytes(result), request[myid]);
delete request[myid];
@@ -232,8 +187,8 @@ contract PointsOracle is Controlled, usingOraclize {
function processRequest(bytes v, Request _request)
internal
{
GitPivotI pivot = GitPivotI(controller);
uint8 pos = 0;
IGitPivot pivot = IGitPivot(controller);
uint256 pos = 0;
string memory temp;
uint256 projectId;
uint256 issueId;
@@ -441,60 +396,4 @@ contract PointsOracle is Controlled, usingOraclize {
}
}
/**
*
*/
function getNextString(bytes _str, uint8 _pos)
internal
constant
returns (string, uint8)
{
uint8 _start = 0;
uint8 end = 0;
uint strl = _str.length;
for (;strl > _pos; _pos++) {
if (_str[_pos] == "\"") { //Found quotation mark
if (_str[_pos-1] != "\\") { //is not escaped
end = _start == 0 ? 0 : _pos;
_start = _start == 0 ? (_pos + 1) : _start;
if (end > 0)
break;
}
}
}
bytes memory str = new bytes(end - _start);
for (_pos = 0; _pos < str.length; _pos++) {
str[_pos] = _str[_start + _pos];
}
for (_pos = end + 1; _pos < _str.length; _pos++) {
if (_str[_pos] == ",") {
_pos++;
break;
} //end
}
return (string(str), _pos);
}
/**
*
*/
function getNextUInt(bytes _str, uint8 _continue)
internal
constant
returns (uint val, uint8 _pos)
{
val = 0;
uint strl = _str.length;
for (_pos = _continue; strl > _pos; _pos++) {
byte bp = _str[_pos];
if (bp == ",") { //Find ends
_pos++;
break;
} else if ((bp >= 48)&&(bp <= 57)) { //only ASCII numbers
val *= 10;
val += uint(bp) - 48;
}
}
return (val, _pos);
}
}
+12 -9
View File
@@ -1,20 +1,22 @@
pragma solidity ^0.4.11;
import "./GitHubAPIReg.sol";
import "./JSONHelper.sol";
import "./management/RegistryIndex.sol";
import "./GitRepository.sol";
import "./common/strings.sol";
import "./common/Controlled.sol";
import "./deploy/KillableModel.sol";
import "./oraclize/oraclizeAPI_0.4.sol";
/**
* @title RepositoryOracle
* Registers the master branch of a Repository for GitHubOracle tracking.
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)]
*/
contract RepositoryOracle is GitHubAPIReg, RegistryIndex {
contract RepositoryOracle is KillableModel, Controlled, RegistryIndex, JSONHelper, usingOraclize {
using strings for string;
using strings for strings.slice;
string private cred = "";
mapping (uint256 => bytes32) public branch;
event NewRepository(address addr, uint256 projectId, string fullName, string defaultBranch);
@@ -33,7 +35,7 @@ contract RepositoryOracle is GitHubAPIReg, RegistryIndex {
//oraclize response callback
function __callback(bytes32 myid, string result, bytes proof) {
OracleEvent(myid, result, proof);
//OracleEvent(myid, result, proof);
require(msg.sender == oraclize.cbAddress());
_setRepository(result);
}
@@ -42,7 +44,7 @@ contract RepositoryOracle is GitHubAPIReg, RegistryIndex {
internal //[85743750, "ethereans/TheEtherian", "master"]
{
bytes memory v = bytes(result);
uint8 pos = 0;
uint256 pos = 0;
uint256 projectId;
(projectId, pos) = getNextUInt(v, pos);
string memory full_name;
@@ -52,13 +54,14 @@ contract RepositoryOracle is GitHubAPIReg, RegistryIndex {
address repoAddr = registry[projectId].addr;
if (repoAddr == 0x0) {
NewRepository(repoAddr, projectId, full_name, default_branch);
GitRepositoryI repo = new GitRepository(projectId, full_name);
GitRepository repo = new GitRepository(projectId, full_name);
repo.changeController(controller);
repoAddr = address(repo);
branch[projectId] = keccak256(default_branch);
setRegistry(repoAddr, projectId, full_name);
setRegistry(projectId, repoAddr, full_name);
} else {
updateIndex(repositories[projectId].name, full_name);
revert(); //TODO: update name
//updateIndex(registry[projectId], full_name);
}
}
//internal helper functions
+12 -9
View File
@@ -1,20 +1,24 @@
pragma solidity ^0.4.11;
pragma solidity ^0.4.17;
import "./GitHubAPIReg.sol";
import "./common/strings.sol";
import "./deploy/KillableModel.sol";
import "./JSONHelper.sol";
import "./oraclize/oraclizeAPI_0.4.sol";
import "./common/Controlled.sol";
import "./management/RegistryIndex.sol";
/**
* @title GitHubUserReg.sol
* Registers GitHub user login to an address
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)]
*/
contract UserOracle is GitHubAPIReg, RegistryIndex {
contract UserOracle is KillableModel, Controlled, RegistryIndex, JSONHelper, usingOraclize {
using strings for string;
using strings for strings.slice;
mapping (bytes32 => UserClaim) userClaim; //temporary db for oraclize user register queries
string private cred = "";
mapping (bytes32 => UserClaim) userClaim; //temporary db for oraclize user register queries
event RegisterUpdated(string name);
@@ -24,8 +28,8 @@ contract UserOracle is GitHubAPIReg, RegistryIndex {
string login;
}
function register(string _githubUser, string _gistId, string _cred) public payable {
require(watchdog != 0x0);
if (bytes(_cred).length == 0) {
_cred = cred;
}
@@ -33,17 +37,16 @@ contract UserOracle is GitHubAPIReg, RegistryIndex {
userClaim[ocid] = UserClaim({sender: msg.sender, login: _githubUser});
}
//oraclize response callback
function __callback(bytes32 myid, string result, bytes proof) public {
OracleEvent(myid, result, proof);
//OracleEvent(myid, result, proof);
require(msg.sender == oraclize.cbAddress());
_register(myid, result);
}
function _register(bytes32 myid, string result) internal {
bytes memory v = bytes(result);
uint8 pos = 0;
uint256 pos = 0;
address addrLoaded;
string memory login;
uint256 userId;
-68
View File
@@ -1,68 +0,0 @@
pragma solidity ^0.4.11;
import "../common/Controlled.sol";
/**
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract BountyBank is Controlled {
enum State {CLOSED, OPEN, CLAIMED}
struct Bounty {
State state;
uint closedAt;
mapping (address => uint) deposits;
mapping (address => uint) claimers;
uint balance;
uint points;
}
mapping (uint => Bounty) bounties;
uint count = 0;
function deposit(uint num) payable {
require(bounties[num].state == State.OPEN);
require(msg.value > 0);
bounties[num].deposits[msg.sender] += msg.value;
bounties[num].balance += msg.value;
}
function withdraw(uint num) {
uint value = bounties[num].deposits[msg.sender];
require(bounties[num].state == State.OPEN && value > 0);
delete bounties[num].deposits[msg.sender];
msg.sender.transfer(value);
}
function open(uint num) onlyController {
require(bounties[num].state != State.CLAIMED);
bounties[num].state = State.OPEN;
}
function setClaimer(uint num, address claimer, uint points) onlyController {
require(bounties[num].state != State.CLAIMED);
bounties[num].claimers[claimer] += points;
bounties[num].points += points;
}
function close(uint num, uint _closedAt) onlyController {
require(bounties[num].state != State.CLAIMED);
bounties[num].state = State.CLOSED;
bounties[num].closedAt = _closedAt;
}
function claim(uint num) {
require (bounties[num].state != State.OPEN);
uint totalPoints = bounties[num].points;
require (totalPoints > 0);
uint points = bounties[num].claimers[msg.sender];
require (points > 0);
delete bounties[num].claimers[msg.sender];
uint award = (bounties[num].balance / totalPoints)*points;
bounties[num].points -= points;
bounties[num].balance -= award;
msg.sender.transfer(award);
}
}
+5 -2
View File
@@ -1,10 +1,13 @@
pragma solidity ^0.4.10;
import "../common/MiniMeToken.sol";
import "../common/Controlled.sol";
import "../token/MiniMeToken.sol";
/**
* @title CollaborationBank
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Share profit between tokenholders.
*/
contract CollaborationBank is Controlled {
@@ -21,7 +24,7 @@ contract CollaborationBank is Controlled {
uint256 public epochLenght;
uint256 public firstEpoch;
function CollaborationBank(MiniMeToken _token, uint _epochLenght) {
function CollaborationBank(MiniMeToken _token, uint _epochLenght) public {
epochLenght = _epochLenght;
firstEpoch = currentEpoch();
token = _token;
@@ -1,37 +1,51 @@
pragma solidity ^0.4.11;
import "../management/TokenLedger.sol";
import "../token/TokenLedger.sol";
import "../common/Controlled.sol";
/**
* @title IssueBank
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* Enable deposits to be withdrawn by points recievers
* @dev Model (library) contract to set agreement between a repository owner and GitPivot
* about the bounty winners.
**/
contract IssueBank is Controlled, TokenLedger {
enum State {OPEN, REFUND, REWARD, FINALIZED }
State public state;
uint public points;
uint public refundNonce;
mapping (address => Reward) public rewards;
address public repoOwner;
contract IssueBankModel is Controlled, TokenLedger {
address public owner; //repository owner
mapping (address => Reward) public rewards; //bounty winners candidates
uint public points; //remaining points to be claimed
State public state; //current issue state
enum State { OPEN, REFUND, REWARD, FINALIZED }
struct Reward {
bool active;
bool active; // repository owner can activate
uint points;
}
modifier onlyRepoOwner{
require (msg.sender == repoOwner);
modifier onlyOwner{
require (msg.sender == owner);
_;
}
function IssueBank(address _repoOwner) {
repoOwner = _repoOwner;
/**
* @dev Model Constructor: Generates a locked state for model being unusable
**/
function IssueBankModel() public {
owner = 0x0;
}
/**
* @dev Instance Constructor: Actual agreement logic initialization.
* @param _owner Repository owner which will accept bounty winners and finalize issue.
**/
function IssueBank(address _owner) public {
require(controller == 0x0);
controller = msg.sender;
owner = _owner;
state = State.OPEN;
}
/**
* @notice deposit ether in bank
**/
@@ -54,6 +68,16 @@ contract IssueBank is Controlled, TokenLedger {
_reward(_tokens);
}
/**
* @notice Repository owner can replace his address
* @param _newOwner
**/
function updateOwner(address _newOwner) onlyOwner {
require(_newOwner != 0x0);
owner = _newOwner;
}
/**
* @notice only contoller may set reward to a single address.
* @param _claimer the beneficiary
@@ -84,7 +108,7 @@ contract IssueBank is Controlled, TokenLedger {
* @notice only the repo owner may confirm reward of addresses
* @param _claimers array of addresses that are eligible to reward
**/
function confirm(address[] _claimers) onlyRepoOwner {
function confirm(address[] _claimers) onlyOwner {
uint len = _claimers.length;
uint nPoints = 0;
for (uint i = 0; i < len; i++) {
@@ -100,7 +124,7 @@ contract IssueBank is Controlled, TokenLedger {
* @notice only the repo owner may confirm reward of single address
* @param _claimer the address that is eligible to reward
**/
function confirm(address _claimer) onlyRepoOwner {
function confirm(address _claimer) onlyOwner {
require(!rewards[_claimer].active);
rewards[_claimer].active = true;
points += rewards[_claimer].points;
@@ -110,7 +134,7 @@ contract IssueBank is Controlled, TokenLedger {
* @notice only repo owner can close deposits and start reward or refund
* If no points confirmed the system will start refund, otherwise reward
*/
function close() onlyRepoOwner {
function close() onlyOwner {
require(state == State.OPEN);
state = points > 0 ? State.REWARD : State.REFUND;
}
@@ -128,47 +152,51 @@ contract IssueBank is Controlled, TokenLedger {
}
/**
* @notice Withdraw tokens
* only avaliable in REWARD state and all points claimed.
*
* @notice withdraw remaining tokens and eth send them to repoOwner
* this might be a case when some tokens were 'forgotten'
* or simply sent after finalized.
* @param _tokens the list of tokens to withdraw.
**/
function withdraw(address[] _tokens) onlyController {
require(state == State.FINALIZED);
if (this.balance > 0) {
owner.send(this.balance);
}
uint len = _tokens.length;
uint amount;
for (uint i = 0; i < len; i++) {
ERC20 token = ERC20(_tokens[i]);
amount = token.balanceOf(this);
address token = _tokens[i];
amount = updateInternalBalance(token);
if (amount > 0) {
withdraw(
token,
repoOwner,
owner,
amount,
0x0
);
}
}
}
/**
* @notice only controller may kill contract and send all remaining eth and tokens to repo owner
* This can only be done when all rewards are claimed.
**/
function kill() onlyController {
require(state == State.FINALIZED);
withdraw(tokens);
selfdestruct(repoOwner);
}
/**
* @dev overwriten to only allow refund in correct state.
* @dev overwriten to only allow refund in correct state and to refund eth
**/
function refund(address _token) returns (bool success) {
require(state == State.REFUND);
success = withdraw(
_token,
msg.sender,
deposits[_token][msg.sender],
msg.sender
);
if(_token == 0x0){
uint v = deposits[0x0][msg.sender];
if (v > 0) {
delete deposits[0x0][msg.sender];
success = msg.sender.send(v);
}
} else {
success = withdraw(
_token,
msg.sender,
deposits[_token][msg.sender],
msg.sender
);
}
}
/**
@@ -249,22 +277,4 @@ contract IssueBank is Controlled, TokenLedger {
}
}
/**
* @title IssueBankFactory
* @author Ricado Guilherme Schmidt <3esmit>
**/
contract IssueBankFactory {
/**
* @notice creates new IssueBank with repoOwner as moderator
**/
function create(address repoOwner) returns(IssueBank) {
IssueBank bank = new IssueBank(repoOwner);
bank.changeController(msg.sender);
return bank;
}
}
+73
View File
@@ -0,0 +1,73 @@
pragma solidity ^0.4.15;
// Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d
library ECRecover {
// ECRecovery Methods
// Duplicate Solidity's ecrecover, but catching the CALL return value
function safer_ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal returns (bool, address) {
// We do our own memory management here. Solidity uses memory offset
// 0x40 to store the current end of memory. We write past it (as
// writes are memory extensions), but don't update the offset so
// Solidity will reuse it. The memory used here is only needed for
// this context.
// FIXME: inline assembly can't access return values
bool ret;
address addr;
assembly {
let size := mload(0x40)
mstore(size, hash)
mstore(add(size, 32), v)
mstore(add(size, 64), r)
mstore(add(size, 96), s)
// NOTE: we can reuse the request memory because we deal with
// the return code
ret := call(3000, 1, 0, size, 128, size, 32)
addr := mload(size)
}
return (ret, addr);
}
function ecrecovery(bytes32 hash, bytes sig) returns (address) {
bytes32 r;
bytes32 s;
uint8 v;
if (sig.length != 65)
return (address(0));
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
v := byte(0, mload(add(sig, 96)))
// Alternative solution:
// 'byte' is not working due to the Solidity parser, so lets
// use the second best option, 'and'
// v := and(mload(add(sig, 65)), 255)
}
// albeit non-transactional signatures are not specified by the YP, one would expect it
// to match the YP range of [27, 28]
//
// geth uses [0, 1] and some clients have followed. This might change, see:
// https://github.com/ethereum/go-ethereum/issues/2053
if (v < 27)
v += 27;
if (v != 27 && v != 28)
return (address(0));
bool ret;
address addr;
(ret, addr) = safer_ecrecover(hash, v, r, s);
return addr;
}
}
-9
View File
@@ -1,9 +0,0 @@
pragma solidity ^0.4.14;
/**
* @title TokenReceiver
* @dev Used by ERC223
*/
contract ERC223Receiver {
function tokenFallback(address _from, uint _value, bytes _data);
}
-15
View File
@@ -1,15 +0,0 @@
pragma solidity ^0.4.14;
import "./ERC20.sol";
import "./ERC677Receiver.sol";
contract ERC677 is ERC20 {
function transferAndCall(address receiver, uint amount, bytes data) returns (bool success) {
require(transfer(receiver, amount));
return _postTransferCall(receiver, amount, data);
}
function _postTransferCall(address receiver, uint amount, bytes data) internal returns (bool success) {
return ERC677Receiver(receiver).tokenFallback(msg.sender, amount, data);
}
}
+32 -2
View File
@@ -691,14 +691,15 @@ library strings {
return "";
uint _len = self._len * (parts.length - 1);
for(uint i = 0; i < parts.length; i++)
for (uint i = 0; i < parts.length; i++) {
_len += parts[i]._len;
}
var ret = new string(_len);
uint retptr;
assembly { retptr := add(ret, 32) }
for(i = 0; i < parts.length; i++) {
for (i = 0; i < parts.length; i++) {
memcpy(retptr, parts[i]._ptr, parts[i]._len);
retptr += parts[i]._len;
if (i < parts.length - 1) {
@@ -709,4 +710,33 @@ library strings {
return ret;
}
/*
* @dev Joins an array of slices, returning a
* newly allocated string.
* @param parts A list of slices to join.
* @return A newly allocated string containing
* all the slices in `parts` joined.
*/
function join(slice[] parts) internal returns (string) {
uint partslen = parts.length;
if (partslen == 0)
return "";
uint _len;
for (uint i = 0; i < partslen; i++) {
_len += parts[i]._len;
}
var ret = new string(_len);
uint retptr;
assembly { retptr := add(ret, 32) }
for (i = 0; i < partslen; i++) {
memcpy(retptr, parts[i]._ptr, parts[i]._len);
retptr += parts[i]._len;
}
return ret;
}
}
+29
View File
@@ -0,0 +1,29 @@
pragma solidity ^0.4.17;
import "./BasicSystemStorage.sol";
/**
* @title AbstractRecoverer
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Abstract recoverer contract that should be crafted to alter `address system` storage
* in delegated logic contracts.
*/
contract AnstractRecoverer is BasicSystemStorage {
/**
* @dev will be callable in emergency state of RecorverableSystem
*/
function recoverSystem(address newSystem) public {
require(msg.sender == consensusContract());
system = newSystem;
}
/**
* @dev returns the consesus contract, can be a multisig or other DAO
* should be implemented by a child contract
*/
function consensusContract() public constant returns(address);
}
+16
View File
@@ -0,0 +1,16 @@
pragma solidity ^0.4.17;
/**
* @title BasicSystemStorage
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Defines system vars in a shared library among Stub and SystemLibraries to
* avoid overwriting wrong storage pointers
*/
contract BasicSystemStorage {
/// protected zone start (RecorverableSystem vars)
address system;
address recover;
address watchdog;
/// protected zone end
}
+33
View File
@@ -0,0 +1,33 @@
pragma solidity ^0.4.17;
/**
* @title DelegatedCall
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Abstract contract that delegates calls by `delegated` modifier to result of `_target()`
*/
contract DelegatedCall {
/**
* @dev delegates the call of this function
*/
modifier delegated {
require(_target().delegatecall(msg.data)); //require successfull delegate call to remote `_target()`
assembly {
let outSize := returndatasize
let outDataPtr := mload(0x40) //load memory
returndatacopy(outDataPtr, 0, outSize) //copy last return into pointer
return(outDataPtr, outSize)
}
assert(false); //should never reach here
_; //never will execute local logic
}
/**
* @dev defines the address for delegation of calls
*/
function _target()
internal
constant
returns(address);
}
+25
View File
@@ -0,0 +1,25 @@
pragma solidity ^0.4.17;
import "./BasicSystemStorage.sol";
/**
* @title KillableModel
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev A contract model that can be killed by a watchdog
*/
contract KillableModel is BasicSystemStorage {
/**
* @dev Library contract constructor initialize watchdog, able to kill the Library in case of
*/
function KillableModel(address _watchdog) public {
watchdog = _watchdog;
}
function emergencyStop() public {
require(msg.sender == watchdog);
selfdestruct(watchdog);
}
}
+24
View File
@@ -0,0 +1,24 @@
pragma solidity ^0.4.4;
contract Migrations {
address public owner;
uint public last_completed_migration;
modifier restricted() {
if (msg.sender == owner) _;
}
function Migrations() public {
owner = msg.sender;
}
function setCompleted(uint _completed) public restricted {
last_completed_migration = _completed;
}
function upgrade(address _newAddress) public restricted {
Migrations upgraded = Migrations(_newAddress);
upgraded.setCompleted(last_completed_migration);
}
}
+56
View File
@@ -0,0 +1,56 @@
pragma solidity ^0.4.17;
import "./BasicSystemStorage.sol";
import "./DelegatedCall.sol";
/**
* @title RecoverableSystem
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @dev Contract that recovers from dead system to recoverer.
*/
contract RecoverableSystem is BasicSystemStorage, DelegatedCall {
function RecoverableSystem(address _system, address _recover) public {
require(isOk(_recover));
system = _system;
recover = _recover;
}
/**
* @dev delegatecall everything (but declared functions) to `_target()`
*/
function () public delegated {
//all goes to system (or recover)
}
/**
* @dev checks if system contains code
*/
function isOk() public constant returns(bool a) {
return isOk(system);
}
/**
* @dev checks if `_a` contains code
*/
function isOk(address _a) internal constant returns(bool r) {
assembly{
r := gt(extcodesize(_a), 0)
}
}
/**
* @dev returns system if system has code, otherwise return recover
*/
function _target()
internal
constant
returns(address)
{
return isOk() ? system : recover;
}
}
+115
View File
@@ -0,0 +1,115 @@
pragma solidity ^0.4.15;
import "../common/Controlled.sol";
/**
* @title Archive
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract Archive is Controlled {
mapping(bytes32 => address) addressMap;
mapping(bytes32 => bytes32) bytes32Map;
mapping(bytes32 => uint) uIntMap;
mapping(bytes32 => int) intMap;
mapping(bytes32 => bool) boolMap;
mapping(bytes32 => string) stringMap;
mapping(bytes32 => bytes) bytesMap;
/**
* Getters
*/
function getAddress(bytes32 _uid) public constant returns (address) {
return addressMap[_uid];
}
function getBytes32(bytes32 _uid) public constant returns (bytes32) {
return bytes32Map[_uid];
}
function getUInt(bytes32 _uid) public constant returns (uint) {
return uIntMap[_uid];
}
function getInt(bytes32 _uid) public constant returns (int) {
return intMap[_uid];
}
function getBoolean(bytes32 _uid) public constant returns (bool) {
return boolMap[_uid];
}
function getString(bytes32 _uid) public constant returns (string) {
return stringMap[_uid];
}
function getBytes(bytes32 _uid) public constant returns (bytes) {
return bytesMap[_uid];
}
/**
* Setters
*/
function putAddress(bytes32 _uid, address value) public onlyController {
addressMap[_uid] = value;
}
function putUInt(bytes32 _uid, uint value) public onlyController {
uIntMap[_uid] = value;
}
function putInt(bytes32 _uid, int value) public onlyController {
intMap[_uid] = value;
}
function putBoolean(bytes32 _uid, bool value) public onlyController {
boolMap[_uid] = value;
}
function putBytes32(bytes32 _uid, bytes32 value) public onlyController {
bytes32Map[_uid] = value;
}
function putString(bytes32 _uid, string value) public onlyController {
stringMap[_uid] = value;
}
function putBytes(bytes32 _uid, bytes value) public onlyController {
bytesMap[_uid] = value;
}
/**
* Deleters
*/
function deleteAddress(bytes32 _uid) public onlyController {
delete addressMap[_uid];
}
function deleteBytes32(bytes32 _uid) public onlyController {
delete bytes32Map[_uid];
}
function deleteUInt(bytes32 _uid) public onlyController {
delete uIntMap[_uid];
}
function deleteInt(bytes32 _uid) public onlyController {
delete intMap[_uid];
}
function deleteBoolean(bytes32 _uid) public onlyController {
delete boolMap[_uid];
}
function deleteString(bytes32 _uid) public onlyController {
delete stringMap[_uid];
}
function deleteBytes(bytes32 _uid) public onlyController {
delete bytesMap[_uid];
}
}
+28
View File
@@ -0,0 +1,28 @@
pragma solidity ^0.4.11;
/**
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* @title NameRegistry
* Interface for Name Registries.
*/
contract NameRegistry {
function getAddr(uint256 _id) public constant returns(address addr);
function getAddr(string _name) public constant returns(address addr);
function getName(address _addr) public constant returns(string name);
mapping (bytes32 => uint256) indexes;
function getId(address _addr) public constant returns(uint256 id){
return indexes[keccak256(_addr)];
}
function getId(string _name) public constant returns(uint256 id) {
return indexes[keccak256(_name)];
}
function _updateIndex(bytes32 _old, bytes32 _new) internal {
indexes[_new] = indexes[_old];
delete indexes[_old];
}
}
@@ -69,8 +69,12 @@ contract usingOraclize {
OraclizeI oraclize;
modifier oraclizeAPI {
if((address(OAR)==0)||(getCodeSize(address(OAR))==0)) oraclize_setNetwork(networkID_auto);
oraclize = OraclizeI(OAR.getAddress());
if((address(OAR)==0)||(getCodeSize(address(OAR))==0))
oraclize_setNetwork(networkID_auto);
if(address(oraclize) != OAR.getAddress())
oraclize = OraclizeI(OAR.getAddress());
_;
}
modifier coupon(string code){
@@ -79,7 +83,7 @@ contract usingOraclize {
_;
}
function oraclize_setNetwork(uint8 /*networkID*/) internal returns(bool){
function oraclize_setNetwork(uint8 networkID) internal returns(bool){
if (getCodeSize(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed)>0){ //mainnet
OAR = OraclizeAddrResolverI(0x1d3B2638a7cC9f2CB3D298A3DA7a90B67E5506ed);
oraclize_setNetworkName("eth_mainnet");
@@ -773,7 +777,7 @@ contract usingOraclize {
}
bytes[3] memory args = [unonce, nbytes, sessionKeyHash];
bytes32 queryId = oraclize_query(_delay, "random", args, _customGasLimit);
oraclize_randomDS_setCommitment(queryId, keccak256(bytes8(_delay), args[1], sha256(args[0]), args[2]));
oraclize_randomDS_setCommitment(queryId, sha3(bytes8(_delay), args[1], sha256(args[0]), args[2]));
return queryId;
}
@@ -805,10 +809,10 @@ contract usingOraclize {
(sigok, signer) = safer_ecrecover(tosignh, 27, sigr, sigs);
if (address(keccak256(pubkey)) == signer) return true;
if (address(sha3(pubkey)) == signer) return true;
else {
(sigok, signer) = safer_ecrecover(tosignh, 28, sigr, sigs);
return (address(keccak256(pubkey)) == signer);
return (address(sha3(pubkey)) == signer);
}
}
@@ -857,6 +861,16 @@ contract usingOraclize {
_;
}
function oraclize_randomDS_proofVerify__returnCode(bytes32 _queryId, string _result, bytes _proof) internal returns (uint8){
// Step 1: the prefix has to match 'LP\x01' (Ledger Proof version 1)
if ((_proof[0] != "L")||(_proof[1] != "P")||(_proof[2] != 1)) return 1;
bool proofVerified = oraclize_randomDS_proofVerify__main(_proof, _queryId, bytes(_result), oraclize_getNetworkName());
if (proofVerified == false) return 2;
return 0;
}
function matchBytes32Prefix(bytes32 content, bytes prefix) internal returns (bool){
bool match_ = true;
@@ -875,7 +889,7 @@ contract usingOraclize {
uint ledgerProofLength = 3+65+(uint(proof[3+65+1])+2)+32;
bytes memory keyhash = new bytes(32);
copyBytes(proof, ledgerProofLength, 32, keyhash, 0);
checkok = (keccak256(keyhash) == keccak256(sha256(context_name, queryId)));
checkok = (sha3(keyhash) == sha3(sha256(context_name, queryId)));
if (checkok == false) return false;
bytes memory sig1 = new bytes(uint(proof[ledgerProofLength+(32+8+1+32)+1])+2);
@@ -887,7 +901,7 @@ contract usingOraclize {
if (checkok == false) return false;
// Step 4: commitment match verification, keccak256(delay, nbytes, unonce, sessionKeyHash) == commitment in storage.
// Step 4: commitment match verification, sha3(delay, nbytes, unonce, sessionKeyHash) == commitment in storage.
// This is to verify that the computed args match with the ones specified in the query.
bytes memory commitmentSlice1 = new bytes(8+1+32);
copyBytes(proof, ledgerProofLength+32, 8+1+32, commitmentSlice1, 0);
@@ -897,7 +911,7 @@ contract usingOraclize {
copyBytes(proof, sig2offset-64, 64, sessionPubkey, 0);
bytes32 sessionPubkeyHash = sha256(sessionPubkey);
if (oraclize_randomDS_args[queryId] == keccak256(commitmentSlice1, sessionPubkeyHash)){ //unonce, nbytes and sessionKeyHash match
if (oraclize_randomDS_args[queryId] == sha3(commitmentSlice1, sessionPubkeyHash)){ //unonce, nbytes and sessionKeyHash match
delete oraclize_randomDS_args[queryId];
} else return false;
@@ -25,7 +25,7 @@ pragma solidity ^0.4.6;
/// affecting the original token
/// @dev It is ERC20 compliant, but still needs to under go further testing.
import "./Controlled.sol";
import "../common/Controlled.sol";
import "./TokenController.sol";
import "./ApproveAndCallFallBack.sol";
@@ -37,13 +37,13 @@ contract MiniMeToken is Controlled {
string public name; //The Token's name: e.g. DigixDAO Tokens
uint8 public decimals; //Number of decimals of the smallest unit
string public symbol; //An identifier: e.g. REP
string public version = 'MMT_0.1'; //An arbitrary versioning scheme
string public version = "MMT_0.1"; //An arbitrary versioning scheme
/// @dev `Checkpoint` is the structure that attaches a block number to a
/// given value, the block number attached is the one that last changed the
/// value
struct Checkpoint {
struct Checkpoint {
// `fromBlock` is the block number that the value was generated from
uint128 fromBlock;
@@ -1,15 +1,17 @@
pragma solidity ^0.4.14;
pragma solidity ^0.4.17;
import "./ERC223.sol";
import "./MiniMeToken.sol";
import "./TokenReceiver.sol";
import "../common/ERC223.sol";
import "../common/MiniMeToken.sol";
import "../common/ERC223Receiver.sol";
/**
* @title TokenLedger
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* Abstract contract for tracking token deposits.
* Token transfers that did not approved and called `receiveApproval` can be tracked by
* Token transfers that did not approved and called `receiveApproval` can be tracked by updateInternalBalance
**/
contract TokenLedger is ERC223Receiver, ApproveAndCallFallBack {
contract TokenLedger is TokenReceiver, ApproveAndCallFallBack {
event Withdrawn(address indexed token, address indexed reciever, uint value);
event Deposited(address indexed token, address indexed sender, uint value, bytes data);
@@ -27,9 +29,10 @@ contract TokenLedger is ERC223Receiver, ApproveAndCallFallBack {
**/
function updateInternalBalance(address _token)
public
returns (uint newBal)
{
uint oldBal = tokenBalances[_token];
uint newBal = ERC20(_token).balanceOf(this);
newBal = ERC20(_token).balanceOf(this);
require(newBal != oldBal);
if (newBal > oldBal) {
register(_token, address(this), newBal - oldBal, new bytes(0));
@@ -43,7 +46,10 @@ contract TokenLedger is ERC223Receiver, ApproveAndCallFallBack {
* @param _from address incoming token
* @param _amount incoming amount
**/
function tokenFallback(address _from, uint _amount, bytes _data) {
function tokenFallback(address _from, uint _amount, bytes _data)
public
returns (bool)
{
register(msg.sender, _from, _amount, _data);
}
@@ -58,7 +64,9 @@ contract TokenLedger is ERC223Receiver, ApproveAndCallFallBack {
address _from,
uint256 _amount,
address _token,
bytes _data)
bytes _data
)
public
{
uint _nonce = nonce;
ERC20 token = ERC20(_token);
@@ -1,8 +1,8 @@
pragma solidity ^0.4.14;
pragma solidity ^0.4.17;
/**
* @title TokenReceiver
* @dev Used by ERC677
* @dev ERC223 and ERC677
*/
contract TokenReceiver {
function tokenFallback(address _from, uint _value, bytes _data) public returns (bool);
+1 -1
View File
@@ -1,5 +1,5 @@
{
"package_name": "githuboracle",
"package_name": "gitpivot",
"version": "0.0.1",
"description": "Tokenize commits and issues",
"authors": [
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "github-oracle",
"name": "gitpivot",
"version": "0.0.1",
"description": "Tokenize commits and issues",
"main": "index.js",