-
Notifications
You must be signed in to change notification settings - Fork 28
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
staking rewards to any #647
Conversation
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 is looking good! When I had originally envisioned this, I was thinking of an external function that just lets the owner of a validation/delegation change their rewards address, which would obviate the need for passing around the address in the initialize
functions. I think your way works just as well, except if the staker wants to change the reward address in between the initialize
and complete
steps. Having the rewards address change in a separate step would also let the caller verify the address is correctly set before calling to disburse the rewards.
We could also set rewardRecipient = owner
when starting a staking period, which would prevent us from having to check if the address is 0 later.
I still need to add the functionality to change the reward-recipient between initialize and complete. As for always setting the reward-recipient (defaulting to the owner), it's cheaper not to set it. I'm happy to do things either way though. It's one of those things where we save the extra storage where it isn't necessary or we make the cost consistent (no matter where you withdraw the reward) |
79a1984
to
0380f82
Compare
I think all that's left is exposing the |
Oh actually, I think I need a couple more tests. Will leave comments in the code. |
0380f82
to
30f27e1
Compare
ca5f8e0
to
c290490
Compare
contracts/validator-manager/tests/PoSValidatorManagerTests.t.sol
Outdated
Show resolved
Hide resolved
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 overall! Just a couple of minor questions and a method name typo.
contracts/validator-manager/interfaces/IPoSValidatorManager.sol
Outdated
Show resolved
Hide resolved
if (rewardRecipient != address(0)) { | ||
$._delegatorRewardRecipients[delegationID] = rewardRecipient; | ||
} |
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.
Would it maybe make sense to set this in initializeEndDelegation
, so that we don't have to pass the parameter down another level?
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 actually just changed this because of this comment.
Is there a problem passing this down? More expensive? I can revert my change, but this definitely is cleaner (ignoring gas cost)
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.
Yeah no, this is good :)
revert InvalidRewardRecipient(rewardRecipient); | ||
} | ||
|
||
PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); |
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.
Idiomatically we always place this at the top of the function before any checks. If a call reverts, it uses all the gas anyway, so there are no potential savings.
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.
What if the address is 0, though?
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.
Either ordering gives exactly the same effects in all cases, since reverted transactions cause all gas to be use, and any side-effects are not saved. Happy to explain more if that doesn't explain it fully
if (rewardRecipient == address(0)) { | ||
revert InvalidRewardRecipient(rewardRecipient); | ||
} | ||
|
||
PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); | ||
|
||
if ($._delegatorStakes[delegationID].owner != _msgSender()) { | ||
revert UnauthorizedOwner(_msgSender()); | ||
} | ||
|
||
if (rewardRecipient == _msgSender()) { | ||
delete $._delegatorRewardRecipients[delegationID]; | ||
} else { | ||
$._delegatorRewardRecipients[delegationID] = rewardRecipient; | ||
} |
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 might be worth encapsulating this logic in a private function and having the external func call the private func. Then we could call the private func from initializeEndDelegation
. Then we wouldn't have the different logical handling that I mentioned in another comment.
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.
See this response. TL;DR I think I could clean that up in a follow up, but I think this works and solves the problem, can we land this PR before it diverges any further from main?
My personal preference is to set the reward-recipient to the owner by default. It is a bit less error prone since we won't need to special case the 0 address. I imagine the storage cost is pretty small. |
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.
Generally looks good to me. I left a comment about preferring to set the owner as the default reward recipient, but I'm fine either way.
90cc2a6
to
a388dc1
Compare
a388dc1
to
8773bcb
Compare
🤔 I actually agree, I think that's the cleaner solution. However... this works, so I think it would make sense to do in a follow up (locking in the tests and everything now). Thoughts @geoff-vball and @bernard-avalabs? |
Why this should be merged
Closes #555
How this works
I use another mapping to set the reward-recipient.
TODO: I should probably add another method that allows the validator to change the recipient before
completeEndValidation
is called.How this was tested
Unit tests
TODO: test delegator reward
How is this documented
TODO