-
Notifications
You must be signed in to change notification settings - Fork 65
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
SIP-31: Fungible StakeSui objects #31
base: main
Are you sure you want to change the base?
SIP-31: Fungible StakeSui objects #31
Conversation
Hey @0xripleys I'm the editor for this SIP- can you please share the write access to this repo with amogh-sui ? |
@amogh-sui invited! |
This is possible and I really like this idea. The main benefit of doing this is that it would immediately enable single-validator LSTs for the entire validator set, which would be pretty cool. | ||
|
||
The tricky part would be managing a unique Coin type + metadata per StakingPool. Some notes: | ||
- We would need a one time witness per StakingPool to create the Coin type. This can be passed into the StakingPool on instantiation. |
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.
Right OTWs are only available in init
function at package publishing times so I'm not sure if this solution is feasible without making some OTW exceptions.
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.
An idea: can we leverage TTO to support this for both newly created and existing StakingPool
objects? E.g.,
Add something like:
public fun add_lst_coin<T>(cap: Receiving<TreasuryCap<T>>, metadata: Receiving<T>, pool: &mut StakingPool) {
// assert cap.total_supply == 0 to ensure there has not been any preminting
// add cap to pool.extra_fields["lst_cap"], which ensures this is the only coin type associated with this pool
// update CoinMetadata fields to whatever standards we want for LST tokens
// share metadata
}
to staking_pool
, and then anyone can publish a package that calls create_currency
in the initializer, then transfers the TreasuryCap
and CoinMetadata
to the StakingPool
object.
This is a bit different than the idea of calling create_currency
inside staking pool, but it won't require OTW exceptions (which are a bit scary), and I think it satisfies the requirements of making this permissionless + compatible with existing StakingPool
's
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, after prototyping an LST on top of my reference implementation I'm kind of against making this a Coin, as I would not be able to store Coins from different validators together in the same vector. This is needed to efficiently do unstake operations (LST -> vector<StakedSui>). If we made FungibleStake a Coin, I would have to do a linear amount of dynamic field reads which doesn't feel good
Is there a public implementation of |
|
Hey sorry for the stupid question I'm not very familiar with the staking system. IIUC this will make it possible to merge different stake objects for the same validator but across different epochs? What makes these different objects fungible? Considering there's an activation period of 1 epoch and then another 1 epoch before they start earning rewards, are these newly created stake objects fungible with the other objects that are already earning rewards? |
This SIP addresses that issue by being removing the restriction of (2) and letting you |
sips/sip-merge-staked-sui.md
Outdated
|
||
/// An FungibleStake object with a value of 1 corresponds to 1 pool token in the Staking pool. | ||
/// This can be a Coin! See the Rationale below. | ||
public struct FungibleStake has key, store { |
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.
NIT: I would favor FungibleStakedSui
or ActivatedStakedSui
to keep the naming schema the same between this object and StakedSui
.
That makes sense, thanks for the clarifiaction! Just to confirm my understanding -- this means that in general you will hold 2 objects, one for staked sui that's pending activation and another fungible one that you merge the activated ones into? |
yep! |
|
public fun fungible_stake_to_sui_amount(pool: &StakingPool, fungible_stake_amount: u64): u64; | ||
public fun sui_to_fungible_stake_amount(pool: &StakingPool, sui_amount: u64): u64; | ||
|
||
public fun join_fungible_stake(self: &mut FungibleStakedSui, other: FungibleStakedSui); |
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 SIP overall!
Can we add method aliases for the join_fungible_stake
and split_fungible_stake
functions?
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, can definitely do that.
## Description Implementation for sui-foundation/sips#31 ## Test plan Unit tests + random tests for the math --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API: --------- Co-authored-by: Emma Zhong <[email protected]>
No description provided.