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

feature/reward-master-pool #95

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open

Conversation

decanus
Copy link
Contributor

@decanus decanus commented Sep 6, 2021

Better model for rewards

@decanus
Copy link
Contributor Author

decanus commented Sep 13, 2021

@maxsam4 probably needs more extensive tests for the math, however shouldn't be too weird as its a copy of MasterChefV2 just isolated.

@decanus decanus marked this pull request as ready for review September 13, 2021 09:52
@@ -12,4 +12,9 @@ contract ERC20Mock is ERC20 {
) ERC20(name, symbol) {
_mint(msg.sender, supply);
}

function safeTransfer(address recipient, uint256 amount) external returns (bool) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sushi doesn't have a safeTransfer function. Maybe you want to use a library that has safeTransfer function.


IRewarder _rewarder = rewarder[address(pool)];
if (address(_rewarder) != address(0)) {
_rewarder.onSushiReward(address(pool), account, account, _pendingSushi, amount);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will allow ops to hold lp hostage by making the _rewarder revert on any transfers. We need a way around that in emergencies.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, this is how MCv2 works, but I agree. Let's throw a try catch around this and ignore reverts. Wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, that's a bug, not a feature. Will be fixed in the next version.

As for how to handle these, I'm a bit split. Perhaps we should just add an emergencyTransfer function that bypasses the rewards stuff.

sometimes, the rewarders run out of tokens, and in those cases, we kinda want the reward claiming to revert for most users, or else they will lose all their rewards.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with the emergencyTransfer function is that its not very good UX, if someone transfers LP tokens from metamask or uses a contract that does a transferFrom, you'll always use transfer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Echoing Mudit on this, it's a pain point of MCv2, but was intended to avoid an exploit. It is a very clear problem for serious LP though whole need ability to be agile with their liquidity, if rewarders run out of tokens, or they emit them all malliciously, LP is held hostage which is a major problem IMO. Interesting to see the solutions around this though.

Btw @decanus, super cool to see rewards being handled on a pool level. A great showcase of the flexibility a system like this offers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I agree with the issue. Let's find a solution that works best so we can get this merged.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matthewlilley check the fix I made, this may work: 7ddc657

try _rewarder.onSushiReward(address(pool), account, account, _pendingSushi + reward.pendingSushi, amount + reward.amount) {
unclaimedRewards[address(pool)][account] = RewardAmount({pendingSushi: 0, amount: 0});
} catch {
unclaimedRewards[address(pool)][account] = RewardAmount({pendingSushi: reward.pendingSushi + _pendingSushi, amount: reward.amount + amount});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imagine if a user has 10 LP tokens. If they call it once while the rewarder fails, on the next call the rewarder is called with a new LP amount of 20, even though the user still only has 10 LP tokens. If the event is e.g. a transfer it is also problematic because the rewards continue to run for two accounts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we need to think about how best to do this. Maybe subtract the rewards.amount from pendingRewards if its greater than 0?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants