Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

stake-pool: Add withdraw-sol command + CLI + docs #2475

Merged
merged 8 commits into from
Oct 6, 2021

Conversation

joncinque
Copy link
Contributor

Problem

People want to withdraw SOL directly from the reserve, but this is currently only permitted if there's nowhere else to withdraw from. There are many valid usecases for someone to withdraw SOL directly from the reserve, especially for restricted pools that want easier control over all the SOL in the pool.

Solution

Add a withdraw-sol instruction! The concept is very similar to deposit-sol, except in reverse. Other additions:

  • sol withdrawal fee: allow managers to specify a different fee for sol withdrawals. this makes sense if you want to encourage stake withdraws
  • sol withdraw authority: forces sol withdrawals to be signed by a particular key
  • add CLI support for withdrawing sol, setting the sol withdrawal fee, and setting the sol withdraw authority
  • update the docs for the new instructions
  • rename fee -> epoch_fee for clarity
  • force not inlining some processor functions because we were blowing the stack size with the addition of the new instruction (who knew?)
  • remove the clock and rent accounts wherever they weren't needed during CPIs to the stake program

@jon-chuang could you take a look at the program changes in c6f1f34 and 819c76c?
@c3pko could you look at the doc changes in bd14d67 ?

Copy link
Contributor

@jon-chuang jon-chuang left a comment

Choose a reason for hiding this comment

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

I've checked the changes to the struct and the processor.

I haven't done such a thorough check on the tests, which are pretty boilerplate.

The processor changes mainly followed the template of withdraw_stake.

The worst thing I could have missed is a missing check of some sort. I've only done a once over to cross reference and all the checks appear to be there.

AccountMeta::new_readonly(*user_transfer_authority, true),
AccountMeta::new(*pool_tokens_from, false),
AccountMeta::new(*reserve_stake_account, false),
AccountMeta::new(*lamports_to, true),
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this a signer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

copy-pasta error! thank you for spotting this

withdrawal_fee: Fee,
stake_deposit_fee: Fee,
stake_referral_fee: u8,
deposit_fee: Fee,
Copy link
Contributor

Choose a reason for hiding this comment

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

prefer if the names were kept as they were to prevent confusion

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 idea is that this is changing the behavior, so that the deposit fee set at init is actually for both stake and sol deposit. it seemed unclear to me that only the stake deposit fee is set at init, but not the sol deposit fee. this way all of them are set the same on init, to minimize surprise to a pool creator. And I didn't want to have to specify each of the fees separately on init, just to keep things simpler.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I missed that... Yeah it's probably an ok compromise

stake_deposit_fee: Fee,
stake_referral_fee: u8,
deposit_fee: Fee,
referral_fee: u8,
Copy link
Contributor

Choose a reason for hiding this comment

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

prefer if the names were kept as they were to prevent confusion

Copy link
Contributor

Choose a reason for hiding this comment

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

overall, it's quite inconsistent which params we include in the initialize instruction...

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 it's true, thankfully it's all configurable afterwards

stake_pool.check_manager(manager_info)?;

if fee.can_only_change_next_epoch() && stake_pool.last_update_epoch < clock.epoch {
return Err(StakePoolError::StakeListAndPoolOutOfDate.into());
}

fee.check_too_high()?;
fee.check_withdrawal(&stake_pool.withdrawal_fee)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

did this check go inside update_fee?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, exactly, i'll flag it for you

match fee {
FeeType::SolReferral(new_fee) => self.sol_referral_fee = *new_fee,
FeeType::StakeReferral(new_fee) => self.stake_referral_fee = *new_fee,
FeeType::Epoch(new_fee) => self.next_epoch_fee = Some(*new_fee),
FeeType::Withdrawal(new_fee) => self.next_withdrawal_fee = Some(*new_fee),
FeeType::StakeWithdrawal(new_fee) => {
new_fee.check_withdrawal(&self.stake_withdrawal_fee)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

ok, I guess it got moved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep

@@ -17,7 +17,7 @@ use {
},
Copy link
Contributor

Choose a reason for hiding this comment

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

tangential discussion but since when was github able to do this with recognizing file name changes? 😍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Huh, that's a good point, i'm not sure, but it's very welcome 😄

@joncinque
Copy link
Contributor Author

@jon-chuang thanks a ton for the review! And you got it all right with regards to withdrawing from the reserve as a stake account vs withdraw sol. the two are meant to be totally equivalent, but the old withdraw_stake version has to use a stake account, to keep things consistent

@joncinque joncinque merged commit b80c10f into solana-labs:master Oct 6, 2021
@joncinque joncinque deleted the sp-withdraw branch October 6, 2021 02:44
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants