Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

withdrawMultiple, darknodeBalances #45

Merged
merged 10 commits into from
May 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- install_deps
- run:
name: Run tests
command: yarn run coverage
command: yarn run coverage && yarn run coveralls

workflows:
build:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
## Solidity smart contracts used by Ren Darknodes

[![CircleCI](https://circleci.com/gh/renproject/darknode-sol.svg?style=shield)](https://circleci.com/gh/renproject/darknode-sol)
[![Coverage Status](https://coveralls.io/repos/github/republicprotocol/republic-sol/badge.svg?branch=master)](https://coveralls.io/github/republicprotocol/republic-sol?branch=master)
[![Coverage Status](https://coveralls.io/repos/github/renproject/darknode-sol/badge.svg?branch=master)](https://coveralls.io/github/renproject/darknode-sol?branch=master)

**`darknode-sol`** contains a collection of Ethereum smart contracts utilized by the Ren Darknodes, written in Solidity. Ren bootstraps off Ethereum as a trusted third-party computer to handle Darknode registration and fee payouts.

Expand Down
42 changes: 26 additions & 16 deletions contracts/DarknodePayment/DarknodePayment.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,28 @@ contract DarknodePayment is Ownable {
cycleTimeout = cycleStartTime.add(cycleDuration);
}

/// @notice Transfers the funds allocated to the darknode to the darknode
/// owner.
///
/// @param _darknode The address of the darknode
/// @param _token Which token to transfer
function withdraw(address _darknode, address _token) public {
address payable darknodeOwner = darknodeRegistry.getDarknodeOwner(_darknode);
require(darknodeOwner != address(0x0), "invalid darknode owner");

uint256 amount = store.darknodeBalances(_darknode, _token);
require(amount > 0, "nothing to withdraw");

store.transfer(_darknode, _token, amount, darknodeOwner);
emit LogDarknodeWithdrew(_darknode, amount, _token);
}

function withdrawMultiple(address _darknode, address[] calldata _tokens) external {
for (uint i = 0; i < _tokens.length; i++) {
withdraw(_darknode, _tokens[i]);
}
}

/// @notice Forward all payments to the DarknodePaymentStore.
function () external payable {
address(store).transfer(msg.value);
Expand All @@ -178,6 +200,10 @@ contract DarknodePayment is Ownable {
return store.availableBalance(_token).sub(unclaimedRewards[_token]);
}

function darknodeBalances(address _darknodeID, address _token) external view returns (uint256) {
return store.darknodeBalances(_darknodeID, _token);
}

/// @notice Changes the current cycle.
function changeCycle() external returns (uint256) {
require(now >= cycleTimeout, "cannot cycle yet: too early");
Expand All @@ -204,22 +230,6 @@ contract DarknodePayment is Ownable {
return currentCycle;
}

/// @notice Transfers the funds allocated to the darknode to the darknode
/// owner.
///
/// @param _darknode The address of the darknode
/// @param _token Which token to transfer
function withdraw(address _darknode, address _token) external {
address payable darknodeOwner = darknodeRegistry.getDarknodeOwner(_darknode);
require(darknodeOwner != address(0x0), "invalid darknode owner");

uint256 amount = store.darknodeBalances(_darknode, _token);
require(amount > 0, "nothing to withdraw");

store.transfer(_darknode, _token, amount, darknodeOwner);
emit LogDarknodeWithdrew(_darknode, amount, _token);
}

/// @notice Deposits token into the contract to be paid to the Darknodes
///
/// @param _value The amount of token deposit in the token's smallest unit.
Expand Down
86 changes: 69 additions & 17 deletions migrations/1_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/// <reference types="../test-ts/typings/truffle" />

const BN = require("bn.js");

const RenToken = artifacts.require("RenToken");
const DarknodePayment = artifacts.require("DarknodePayment");
const DarknodePaymentStore = artifacts.require("DarknodePaymentStore");
Expand All @@ -13,36 +15,46 @@ module.exports = async function (deployer, network) {

const VERSION_STRING = `${network}-${config.VERSION}`;

let tokens = [];
let tokens = new Map();

if (network.match("kovan")) {
RenToken.address = "0x2cd647668494c1b15743ab283a0f980d90a87394";
DarknodeSlasher.address = "0x0000000000000000000000000000000000000000";
DarknodeRegistry.address = "0x1C6309618338D0EDf9a7Ea8eA18E060fD323020D";
DarknodePayment.address = "";
tokens = [
"0xc4375b7de8af5a38a93548eb8453a498222c4ff2",
"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"0x2a8368d2a983a0aeae8da0ebc5b7c03a0ea66b37",
"0xd67256552f93b39ac30083b4b679718a061feae6",
];
DarknodeRegistryStore.address = "0x88e4477e4fdd677aee2dc9376471d45c198669fa";
DarknodePayment.address = "0x89693dd95c6149B7e67df8c5FCeEF0af91d6E29b";
DarknodePaymentStore.address = "0xA9411C3AD1fBE168fd119A3B32fB481a0b9877A9";
tokens = new Map()
.set("DAI", "0xc4375b7de8af5a38a93548eb8453a498222c4ff2")
.set("ETH", "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE")
.set("zBTC", "0x2a8368d2a983a0aeae8da0ebc5b7c03a0ea66b37")
.set("zZEC", "0xd67256552f93b39ac30083b4b679718a061feae6");
} else {
RenToken.address = "";
DarknodeSlasher.address = "";
DarknodeRegistry.address = "";
DarknodeRegistryStore.address = "";
DarknodePayment.address = "";
DarknodePaymentStore.address = "";
}

if (!RenToken.address) {
console.log("Deploying RenToken");
await deployer.deploy(RenToken);
}

/** DARKNODE REGISTRY *****************************************************/
if (!DarknodeRegistry.address) {
console.log("Deploying DarknodeRegistryStore");
await deployer.deploy(
DarknodeRegistryStore,
VERSION_STRING,
RenToken.address,
);
}

if (!DarknodeRegistry.address) {
console.log("Deploying DarknodeRegistry");
await deployer.deploy(
DarknodeRegistry,
VERSION_STRING,
Expand All @@ -52,52 +64,92 @@ module.exports = async function (deployer, network) {
config.MINIMUM_POD_SIZE,
config.MINIMUM_EPOCH_INTERVAL
);
}

const darknodeRegistryStore = await DarknodeRegistryStore.at(DarknodeRegistryStore.address);
if ((await darknodeRegistryStore.owner()) !== DarknodeRegistry.address) {
console.log("Linking DarknodeRegistryStore and DarknodeRegistry")
// Initiate ownership transfer of DNR store
const darknodeRegistryStore = await DarknodeRegistryStore.at(DarknodeRegistryStore.address);
await darknodeRegistryStore.transferOwnership(DarknodeRegistry.address);

// Claim ownership
const darknodeRegistry = await DarknodeRegistry.at(DarknodeRegistry.address);
await darknodeRegistry.claimStoreOwnership();
}

/** SLASHER **************************************************************/
/** SLASHER **************************************************************/
if (!DarknodeSlasher.address) {
console.log("Deploying DarknodeSlasher");
await deployer.deploy(
DarknodeSlasher,
DarknodeRegistry.address,
);
}

const darknodeRegistry = await DarknodeRegistry.at(DarknodeRegistry.address);
if ((await darknodeRegistry.slasher()) != DarknodeSlasher.address) {
console.log("Linking DarknodeSlasher and DarknodeRegistry")
// Update slasher address
// const darknodeRegistry = await DarknodeRegistry.at(DarknodeRegistry.address);
await darknodeRegistry.updateSlasher(DarknodeSlasher.address);
}

/** DARKNODE PAYMENT ******************************************************/
if (!DarknodePayment.address) {
if (!DarknodePaymentStore.address) {
console.log("Deploying DarknodePaymentStore");
await deployer.deploy(
DarknodePaymentStore,
VERSION_STRING,
);
}

let changeCycle = false;
let registerTokens = false;
if (!DarknodePayment.address) {
// Deploy Darknode Payment
console.log("Deploying DarknodePayment");
await deployer.deploy(
DarknodePayment,
VERSION_STRING,
DarknodeRegistry.address,
DarknodePaymentStore.address,
0, // Cycle Duration (updated below, after a cycle has been called)
);
changeCycle = true;
registerTokens = true;
}

if (registerTokens) {
const darknodePayment = await DarknodePayment.at(DarknodePayment.address);
for (const [tokenName, tokenAddress] of tokens) {
process.stdout.write(`\rRegistering tokens in DarknodePayment: ${tokenName}\t\t`);
await darknodePayment.registerToken(tokenAddress);
}
console.log("\rRegistering tokens in DarknodePayment\t\t");
}

const darknodePayment = await DarknodePayment.at(DarknodePayment.address);

const darknodePaymentStore = await DarknodePaymentStore.at(DarknodePaymentStore.address);
if (await darknodePaymentStore.owner() !== DarknodePayment.address) {
console.log("Linking DarknodePaymentStore and DarknodePayment")
// Initiate ownership transfer of DarknodePaymentStore
const darknodePaymentStore = await DarknodePaymentStore.at(DarknodePaymentStore.address);
await darknodePaymentStore.transferOwnership(DarknodePayment.address);

// Update DarknodePaymentStore address
const darknodePayment = await DarknodePayment.at(DarknodePayment.address);
await darknodePayment.claimStoreOwnership();
}

for (const token of tokens) {
await darknodePayment.registerToken(token);
if (changeCycle) {
try {
console.log("Calling darknodePayment.changeCycle()");
await darknodePayment.changeCycle();
} catch (error) {
console.error("Unable to call darknodePayment.changeCycle()");
}
await darknodePayment.changeCycle();
}

if (new BN(await darknodePayment.cycleDuration()).toNumber() !== config.DARKNODE_PAYMENT_CYCLE_DURATION_SECS) {
console.log(`Updating cycle duration to ${config.DARKNODE_PAYMENT_CYCLE_DURATION_SECS}`);
await darknodePayment.updateCycleDuration(config.DARKNODE_PAYMENT_CYCLE_DURATION_SECS);
}
}
12 changes: 5 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
"coverage": "if [ -d \"test\" ]; then yarn run warn; else yarn run coverage:ts; fi;",
"merge": "sol-merger \"./contracts/**/*.sol\"",
"warn": "echo \"Refusing to overwrite 'test' directory. Run '\\033[1;33myarn run clean\\033[0m'.\n\"",
"test:ts": "trap \"yarn run clean\" INT TERM; (yarn run bindings:ts && tsc && truffle test); yarn run clean",
"coverage:ts": "trap \"yarn run clean\" INT TERM; (yarn run bindings:ts && tsc && solidity-coverage); yarn run clean",
"test:ts": "trap \"yarn run clean\" INT TERM; (yarn run bindings:ts && tsc && truffle test) && yarn run clean",
"coverage:ts": "trap \"yarn run clean\" INT TERM; (yarn run bindings:ts && tsc && solidity-coverage) && yarn run clean",
"bindings:ts": "truffle compile && ./node_modules/.bin/abi-gen --abis 'build/contracts/*.json' --output ./test-ts/typings/bindings --template './test-ts/typings/bindings/templates/contract.handlebars' --partials './test-ts/typings/bindings/templates/partials/*.handlebars' 1> /dev/null",
"bindings:go": "solc --allow-paths . --combined-json bin,abi,userdoc,devdoc,metadata contracts/**/*.sol | abigen -pkg bindings --out bindings.go --abi -",
"deployToKovan": "truffle migrate --network kovan && yarn run merge .merged/kovan",
"postinstall": "patch-package"
"coveralls": "cat ./coverage/lcov.info | coveralls"
},
"dependencies": {
"openzeppelin-solidity": "2.2.0"
Expand All @@ -37,13 +37,12 @@
"eth-gas-reporter": "^0.1.12",
"ganache-cli": "^6.4.3",
"js-sha3": "^0.8.0",
"patch-package": "^6.1.2",
"postinstall-postinstall": "^2.0.0",
"sol-merger": "^0.1.3",
"solc": "0.5.7",
"solidity-coverage": "0.6.0-beta.5",
"solidity-coverage": "github:rotcivegaf/solidity-coverage#5875f5b7bc74d447f3312c9c0e9fc7814b482477",
"truffle": "5.0.14",
"truffle-hdwallet-provider": "^1.0.0-web3one.5",
"truffle-hdwallet-provider": "1.0.8",
"tslint": "^5.16.0",
"typescript": "^3.4.5",
"underscore": "^1.9.1",
Expand All @@ -56,4 +55,3 @@
"solc": "^0.5.7"
}
}

71 changes: 0 additions & 71 deletions patches/solidity-coverage+0.6.0-beta.5.patch

This file was deleted.