-
Notifications
You must be signed in to change notification settings - Fork 157
Set indexer rewards destination #450
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
Conversation
abarmat
commented
Feb 15, 2021
- Indexer can set a rewards destination for indexing rewards after closing an allocation and for rebate claims
- If rewards destination is set to zero, indexing rewards are restaked
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- call
setRewardsDestination(address _destination)
from your indexer. - close allocation, which will call
_distributeRewards
and then_sendRewards
Clean and simple, I like it!
@@ -82,3 +82,7 @@ contract StakingV1Storage is Managed { | |||
// Allowed AssetHolders: assetHolder => is allowed | |||
mapping(address => bool) public assetHolders; | |||
} | |||
|
|||
contract StakingV2Storage is StakingV1Storage { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice proxy skillz
require(graphToken.transfer(alloc.indexer, tokensToClaim), "!transfer"); | ||
} | ||
} | ||
_sendRewards(graphToken, tokensToClaim, alloc.indexer, restake); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means the indexer agent has to be updated too right? Since this is only for query fees, I think its ok to not have this feature in the agent for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So to not change the current claim() interface, if you pass this method restake=true it will restake if restake=false it will send rewards out.
Any tests planned to be added? |
Yes, I'm pushing them in a minute |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general looks good, looking forward to see the tests
* @param _destination Rewards destination address. If set to zero, rewards will be restaked | ||
*/ | ||
function setRewardsDestination(address _destination) public override { | ||
rewardsDestination[msg.sender] = _destination; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ariel slacked me saying he will add an event here, good idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make it external? This is what the interface shows, seems we are no using it within the contract
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
event added :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll change it to be external. An event was added to this function too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will _destination be set up via Remix or some key in Agent config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setRewardsDestination()
is a function that needs to be called by the indexer address (the one that staked), in the case of an indexer through a TokenLock it needs be called initially through Remix. The feature can be potentially integrated in the frontend too.
@@ -82,3 +82,7 @@ contract StakingV1Storage is Managed { | |||
// Allowed AssetHolders: assetHolder => is allowed | |||
mapping(address => bool) public assetHolders; | |||
} | |||
|
|||
contract StakingV2Storage is StakingV1Storage { | |||
mapping(address => address) public rewardsDestination; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could add a comment here to describe what rewardsDestination
is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea
@@ -717,6 +717,14 @@ contract Staking is StakingV1Storage, GraphUpgradeable, IStaking { | |||
_withdraw(msg.sender); | |||
} | |||
|
|||
/** | |||
* @dev Set the destination where to send rewards. | |||
* @param _destination Rewards destination address. If set to zero, rewards will be restaked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great idea that set to 0 = restaked. this way, when the upgrade happens, it will automatically be set so that everyone is re-staking. we won't run into any breaks
address destination = rewardsDestination[_beneficiary]; | ||
require( | ||
_graphToken.transfer( | ||
destination == address(0) ? _beneficiary : destination, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this ternary is not needed. If we got this far, we already know that rewardsDestination[_beneficiary] != 0
this would work:
require(_graphToken.transfer(rewardsDestination[beneficiary]), _amount, "!transfer");
wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It depends, when the function is called from _claim() it might not be the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you are right ! there is nothing wrong with this code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests added look good!
test/rewards/rewards.test.ts
Outdated
expect(toRound(afterIndexer1Balance)).eq( | ||
toRound(beforeIndexer1Balance.add(expectedIndexingRewards)), | ||
) | ||
// Check indexing rewards are sent from the staking contract |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it more accurate to say check indexing rewards were not sent to the staking contract
? (basically they get minted and send directly to the indexer AFAICT)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, what I tried to say is that rewards are out of the staking contract
test/rewards/rewards.test.ts
Outdated
const afterStakingBalance = await grt.balanceOf(staking.address) | ||
|
||
// Check that rewards are put into indexer stake | ||
// NOTE: calculated manually on a spreadsheet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note sure what this note really means
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is an outdated comment from the test I used as base for this one, I'll update it
I did some benchmark of gas usage for the solution that send rewards directly and the one that uses a rewards pool:
Sending directly to the beneficiary on close is about 4% more expensive. So it might be a good idea to have a rewards pool where multiple rewards across many @davekaj wdyt? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changes look good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. It would be nice to run some tests before actually merging to master.
which makes me think - what should our strategy be for merging to master?
My first thought is that we should only merge to master when the changes are actually deployed to mainnet. Meaning we could create a dev branch or something right now.
I am open to other suggestions!
Just a suggestion, but you're welcome to copy some of what we do here https://github.com/superfluid-finance/protocol-monorepo
Patch versions are updated on releasing to canary |
…atible with previously deployed contracts