Skip to content
This repository has been archived by the owner on Nov 28, 2021. It is now read-only.

Ref/update claim rewards interface #77

Draft
wants to merge 21 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 28 additions & 24 deletions contracts/RenPool.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IDarknodeRegistry.sol";
import "../interfaces/IDarknodePayment.sol";
import "../interfaces/IClaimRewards.sol";
import "../interfaces/IClaimRewardsV1.sol";
fede-rodes marked this conversation as resolved.
Show resolved Hide resolved
import "../interfaces/IGateway.sol";
// TODO: use safeMath
// TODO: Ownable + Ownable.initialize(_owner);
Expand All @@ -24,8 +25,6 @@ contract RenPool {
uint256 public ownerFee; // Percentage
uint256 public nodeOperatorFee; // Percentage

uint64 public nonce;

bool public isLocked;
// ^ we could use enum instead POOL_STATUS = { OPEN /* 0 */, CLOSE /* 1 */ }

Expand All @@ -35,7 +34,7 @@ contract RenPool {
IERC20 public renToken;
IDarknodeRegistry public darknodeRegistry;
IDarknodePayment public darknodePayment;
IClaimRewards public claimRewards;
IClaimRewardsV1 public claimRewards;
IGateway public gateway; // OR IMintGateway????

event RenDeposited(address indexed _from, uint256 _amount);
Expand All @@ -51,7 +50,7 @@ contract RenPool {
* @param _renTokenAddr The REN token contract address.
* @param _darknodeRegistryAddr The DarknodeRegistry contract address.
* @param _darknodePaymentAddr The DarknodePayment contract address.
* @param _claimRewardsAddr The ClaimRewards contract address.
* @param _claimRewardsAddr The ClaimRewardsV1 contract address.
* @param _gatewayAddr The Gateway contract address.
* @param _owner The protocol owner's address. Possibly a multising wallet.
* @param _bond The amount of REN tokens required to register a darknode.
Expand All @@ -71,14 +70,13 @@ contract RenPool {
renToken = IERC20(_renTokenAddr);
darknodeRegistry = IDarknodeRegistry(_darknodeRegistryAddr);
darknodePayment = IDarknodePayment(_darknodePaymentAddr);
claimRewards = IClaimRewards(_claimRewardsAddr);
claimRewards = IClaimRewardsV1(_claimRewardsAddr);
gateway = IGateway(_gatewayAddr);
bond = _bond;
isLocked = false;
totalPooled = 0;
ownerFee = 5;
nodeOperatorFee = 5;
nonce = 0;

// TODO: register pool into RenPoolStore
}
Expand Down Expand Up @@ -302,15 +300,6 @@ contract RenPool {
emit EthWithdrawn(nodeOperator, balance);
}

/**
* @notice Transfer rewards from darknode to darknode owner prior to calling claimDarknodeRewards.
*
* @param _tokens List of tokens to transfer. (here we could have a list with all available tokens)
*/
function transferRewardsToDarknodeOwner(address[] calldata _tokens) external {
darknodePayment.withdrawMultiple(address(this), _tokens);
}

/**
* @notice Claim darknode rewards.
*
Expand All @@ -323,18 +312,18 @@ contract RenPool {
*/
function claimDarknodeRewards(
string memory _assetSymbol,
uint256 _amount, // avoid this param, read from user balance instead. What about airdrops?
address _recipientAddress
address _recipientAddress,
uint256 _amount // avoid this param, read from user balance instead. What about airdrops?
)
external
returns(uint256, uint256)
returns(uint256)
{
// TODO: check that sender has the amount to be claimed
// TODO: check that sender has the amount to be claimed
uint256 fractionInBps = 10_000; // TODO: this should be the share of the user for the given token
uint256 sig = claimRewards.claimRewardsToEthereum(_assetSymbol, _recipientAddress, fractionInBps);
nonce += 1;
uint256 nonce = claimRewards.claimRewardsToEthereum(_assetSymbol, _recipientAddress, fractionInBps);
console.log("nonce", nonce);

return (sig, nonce);
return nonce;
// bytes32 pHash = keccak256(abi.encode(_assetSymbol, _recipientAddress));
// bytes32 nHash = keccak256(abi.encode(nonce, _amount, pHash));

Expand All @@ -343,7 +332,6 @@ contract RenPool {
/*
const nHash = randomBytes(32);
const pHash = randomBytes(32);

const hash = await gateway.hashForSignature.call(
pHash,
value,
Expand All @@ -356,5 +344,21 @@ contract RenPool {
);
See: https://github.com/renproject/gateway-sol/blob/7bd51d8a897952a31134875d7b2b621e4542deaa/test/Gateway.ts
*/

/*
// Construct the payload hash and mint new tokens using the Gateway
// contract. This will verify the signature to ensure the Darknodes have
// received the Bitcoin.
bytes32 pHash =
keccak256(abi.encode(_beneficiary, _startTime, _duration));
uint256 finalAmountScaled =
registry.getGatewayBySymbol("BTC").mint(
pHash,
_amount,
_nHash,
_sig
fede-rodes marked this conversation as resolved.
Show resolved Hide resolved
);
See: https://github.com/renproject/gateway-sol/blob/master/contracts/Gateway/examples/Vesting.sol
*/
}
}
2 changes: 1 addition & 1 deletion hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const networks = {
darknodeRegistryAddr: '0x9954C9F839b31E82bc9CA98F234313112D269712',
darknodeRegistryStoreAddr: '0x9daa16aA19e37f3de06197a8B5E638EC5e487392',
darknodePaymentAddr: '0x023f2e94C3eb128D3bFa6317a3fF860BF93C1616',
claimRewardsAddr: '0x7F8f7Aff44a63f61b7a120Ef2c34Ea2c4D9bD216',
claimRewardsAddr: '0x64C8bdfE42cFFC41D9ca6617350c5F5371DdD0F7',
gatewayAddr: '0x0000000000000000000000000000000000000000',
},
}
Expand Down
25 changes: 0 additions & 25 deletions interfaces/IClaimRewards.sol

This file was deleted.

51 changes: 51 additions & 0 deletions interfaces/IClaimRewardsV1.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.7;

// Source: https://kovan.etherscan.io/address/0x64C8bdfE42cFFC41D9ca6617350c5F5371DdD0F7#code

interface IClaimRewardsV1 {
/**
* claimRewardsToChain allows darknode operators to withdraw darknode
* earnings, as an on-chain alternative to the JSON-RPC claim method.
*
* It will the operators total sum of rewards, for all of their nodes.
*
* @param assetSymbol_ The token symbol.
* E.g. "BTC", "DOGE" or "FIL".
* @param recipientAddress_ An address on the asset's native chain, for
* receiving the withdrawn rewards. This should be a string as
* provided by the user - no encoding or decoding required.
* E.g.: "miMi2VET41YV1j6SDNTeZoPBbmH8B4nEx6" for BTC.
* @param recipientChain_ A string indicating which chain the rewards should
* be withdrawn to. It should be the name of the chain as expected by
* RenVM (e.g. "Ethereum" or "Solana"). Support for different chains
* will be rolled out after this contract is deployed, starting with
* "Ethereum", then other host chains (e.g. "Polygon" or "Solana")
* and then lock chains (e.g. "Bitcoin" for "BTC"), also represented
* by an empty string "".
* @param recipientPayload_ An associated payload that can be provided along
* with the recipient chain and address. Should be empty if not
* required.
* @param fractionInBps_ A value between 0 and 10000 (inclusive) that
* indicates the percent to withdraw from each of the operator's
* darknodes. The value should be in BPS, meaning 10000 represents
* 100%, 5000 represents 50%, etc.
* @return nonce
*/
function claimRewardsToChain(
string memory assetSymbol_,
string memory recipientAddress_,
string memory recipientChain_,
bytes memory recipientPayload_,
uint256 fractionInBps_
) external returns(uint256);

/**
* `claimRewardsToEthereum` calls `claimRewardsToChain` internally.
*/
function claimRewardsToEthereum(
string memory assetSymbol_,
address recipientAddress_,
uint256 fractionInBps_
) external returns (uint256);
}
11 changes: 6 additions & 5 deletions test/RenPool.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,9 @@ describe('RenPool contract test', function () {
expect(await renPool.publicKey()).to.equalIgnoreCase(PUBLIC_KEY);
});

it('should transfer reward to darknode owner', async function () {
await renToken.connect(bob).approve(renPool.address, POOL_BOND);
await renPool.connect(bob).deposit(POOL_BOND);

it.only('should transfer rewards to darknode owner', async function () {
await renToken.connect(alice).approve(renPool.address, POOL_BOND);
await renPool.connect(alice).deposit(POOL_BOND);
await renPool.connect(nodeOperator).approveBondTransfer();
await renPool.connect(nodeOperator).registerDarknode(NODE_ID, PUBLIC_KEY);

Expand All @@ -359,7 +358,9 @@ describe('RenPool contract test', function () {
await increaseMonth();
await darknodeRegistry.epoch();

await renPool.transferRewardsToDarknodeOwner([renBTCAddr]);
const nonce = await renPool.claimDarknodeRewards('BTC', alice.address, bn(1));
// expect(nonce).to.be.gte(0);
console.log(nonce);
// ^ OBSERVATION: not sure if the above code is actually doing anything,
// we need a way to query the darknode's balance and make sure the
// balance is actually being transferred.
Expand Down