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
42 changes: 26 additions & 16 deletions contracts/DarknodePayment/DarknodePayment.sol
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,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 @@ -182,6 +204,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 @@ -208,22 +234,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
87 changes: 69 additions & 18 deletions migrations/1_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// <reference types="../test-ts/typings/truffle" />

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

const RenToken = artifacts.require("RenToken");
const DarknodePayment = artifacts.require("DarknodePayment");
const DarknodePaymentStore = artifacts.require("DarknodePaymentStore");
Expand All @@ -14,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 @@ -53,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} `);
vinceau marked this conversation as resolved.
Show resolved Hide resolved
await darknodePayment.registerToken(tokenAddress);
}
console.log("\rRegistering tokens in DarknodePayment ");
vinceau marked this conversation as resolved.
Show resolved Hide resolved
}

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) {
console.log(`Updating cycle duration to ${config.DARKNODE_PAYMENT_CYCLE_DURATION}`);
await darknodePayment.updateCycleDuration(config.DARKNODE_PAYMENT_CYCLE_DURATION);
}
}
2 changes: 1 addition & 1 deletion migrations/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ module.exports = {
MINIMUM_BOND: new BN(100000).mul(new BN(10).pow(new BN(18))),
MINIMUM_POD_SIZE: 3, // 24 in production
MINIMUM_EPOCH_INTERVAL: 2, // 14400 in production
DARKNODE_PAYMENT_CYCLE_DURATION: 7, // 30 in production (in days)
DARKNODE_PAYMENT_CYCLE_DURATION: 0, // 30 in production (in days)
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"solc": "0.5.7",
"solidity-coverage": "0.6.0-beta.5",
"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 @@ -55,4 +55,4 @@
"resolutions": {
"solc": "^0.5.7"
}
}
}