Replies: 9 comments 7 replies
-
Needed by Sam from SparkDAO: |
Beta Was this translation helpful? Give feedback.
-
One more request from 5ive: |
Beta Was this translation helpful? Give feedback.
-
The objective, as I understand it, is to allow the staking of tokens in the stream which is the sum of IMO the prerequisite for this is that stream must be transferrable and non-cancelable. I've crafted a basic implementation that accomplishes this: See code snippet
contract StakingRewards {
ISablierV2Lockup public lockup;
uint256 public rewardRatePerToken;
address public stakingAsset;
address public rewardToken;
mapping(address => uint256) private _lastTimeRewardUpdated;
mapping(address => uint256[]) private _streamIds;
mapping(address => uint256) private _rewards;
function stake(uint256 streamId) external {
require(stakingAsset == lockup.getAsset(streamId), "wrong asset");
// update previous rewards
_updateRewards(msg.sender);
// transfer stream to this contract requires it to be transferrable and non-cancelable
lockup.transferFrom(msg.sender, address(this), streamId);
// update ownership
_streamIds[msg.sender].push(streamId);
}
function _updateRewards(address account) internal {
uint256 ids = _streamIds[account];
uint256 rewardPeriod = block.timestamp - _lastTimeRewardUpdated[account];
_lastTimeRewardUpdated[account] = block.timestamp;
// calculate rewards for each stream
for (uint256 i; i < ids.length; ++i) {
uint256 tokensInLockup = lockup.withdrawableAmountOf(ids[i]) + lockup.refundableAmountOf(ids[i]);
_rewards[account] += rewardRatePerToken * tokensInLockup * rewardPeriod;
}
}
function unstake(uint256 streamId) external {
require(lockup.getRecipient(streamId) == address(this), "not owned");
// update previous rewards
_updateRewards(msg.sender);
// transfer stream back to user
lockup.transferFrom(address(this), msg.sender, streamId);
// update array
_removeFromStreamArray(msg.sender, streamId);
}
function claimAllRewards() external {
// Update previous rewards
_updateRewards(msg.sender);
// Set rewards to zero
uint256 rewards = _rewards[msg.sender];
_rewards[msg.sender] = 0;
// Transfer rewards
rewardToken.transfer(msg.sender, rewards);
}
} We can provide a framework or example code to our users to enable staking. |
Beta Was this translation helpful? Give feedback.
-
Félix from Salad asked if we knew any protocols that allow you to lock up an NFT for a certain period of time, a sort of end-to-end staking system for Sablier NFTs. They wanted this to have the ability to airdrop token holders that are staking their NFT. |
Beta Was this translation helpful? Give feedback.
-
One more request from VitaDAO: |
Beta Was this translation helpful? Give feedback.
-
A question regarding the request. Who is the actor that wants to stake the tokens? Is it the sender, for example, a protocol that distributes its treasury to the team/members, etc., or is it the recipients (staking in advance), who will supposedly own the assets by the end of the stream? |
Beta Was this translation helpful? Give feedback.
-
I've spent a lot of time working on this as well as debating with Andrei. And I came up with the following conclusion: Staking in itself is a complex feature and many design decisions can vary from user to user. Take the following questions:
We can provide a full deployment-ready contract but it would not solve for all the users. Another problem with writing a production-ready template is that it would make it hard for integrators to understand the core logic of the contract. Our objective should be to provide the basic minimum implementation to make them understand how Sablier NFTs can be used for staking. There are a few important questions:
Everything else depends on the user's requirement and can be learned from other staking products. As a next step, I would like to hear from all of you.
|
Beta Was this translation helpful? Give feedback.
-
This is why staking contract template is important alongside a doc on "things to remember for staking". (PS: I have made good progress) |
Beta Was this translation helpful? Give feedback.
-
We get this feature request a lot. How can we enable support for staking streams?
Beta Was this translation helpful? Give feedback.
All reactions