Skip to content

Commit

Permalink
Merge pull request #45 from renproject/withdraw-multiple
Browse files Browse the repository at this point in the history
withdrawMultiple, darknodeBalances
  • Loading branch information
0x31 committed May 6, 2019
2 parents f59ada0 + 6e0c1d7 commit a3d5bbb
Show file tree
Hide file tree
Showing 10 changed files with 418 additions and 1,130 deletions.
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.

0 comments on commit a3d5bbb

Please sign in to comment.