---
# System prepended metadata

title: '[SOCEAN] Stake pool architectural design'

---

# [SOCEAN] Stake pool architectural design

I think there are at least three different ways to build out a stake pool. The main questions are how to handle deposits and withdrawals.

## Using one validator for deposits and withdrawals

Jon Cinque suggests to have a "preferred" validator for deposits and withdrawals. Discord link [here](https://discord.com/channels/428295358100013066/766355323580579901/859013899281498123)

Deposits: There is a SolDeposit instruction. `SolDeposit` takes in just SOL and any validator (must be the preferred deposit validator if there is one). The instruction creates a new transient stake account on that validator with all of the SOL provided, and mints stake pool tokens with some discount.

The stake pool has multiple transient accounts for each validator, likely maximum of 20 depending on how many can be fit in the update instruction. During the update phase at the start of an epoch, we can still update the balance on one validator in one instruction.

Withdrawals: The stake pool splits off a new account from that preferred validator and gives it to the user. If there is not enough SOL in that validator, it will take from the other validators in descending order of preference, and if there are not enough stSOL in all the validators (a big edge case), it will withdraw from transient activating stake.

Issues with this design:

- What happens once the maximum amount of transient accounts have been created? 
- Why is it important to update the balance on one validator in one instruction?
- Having a preferred validator account would allow some edge case arbitrage. Suppose a validator or subset of validators in the stake pool are about to be slashed (or maybe even that their performance this epoch is not up to snuff). And further suppose that the preferred validator is not about to be slashed. Then folks could escape slashing by withdrawing from the preferred validator.

## Withdrawing proportionally from all validators for deposits and withdrawals

Deposits: Users deposit unstaked SOL into a program account (could be the reserve stake account). We immediately mint them SOCN tokens, and create a new transient stake account for each validator.
 
Withdrawals: Users make a withdrawal request by depositing SOCN, which immediately burns the SOCN. We split off new stake accounts proportionally from each validator stake account. If there is not enough stSOL in each validator stake account, we withdraw from transient activating stake accounts.

Issues with this design: 

- A lot of transient stake accounts are created: N for each deposit, N for each withdrawal. I suppose it is possible to batch the deposit transactions until the end of the epoch (in effect, a "settlement-period-lite"). But we still need N transient stake accounts to be created for each withdrawal. However, Jon Cinque tells me that "This can only work with max 15 validators at the moment because of limitations in transaction size":

> The whole idea is that you need some place to store intermediate state if you have lots of validators to withdraw from, and can't do it in just one 1 instruction.  If you have 1000 validators in the stake pool, you can't process all of them at once, so at each instruction you need to know how much has been processed, and what's still left.

- Jon Cinque suggests some sort of intermediate data structure to store the above state, but there might be some issues here if the withdrawal process crosses an epoch boundary:

> [7:23 PM] jon!: You could make a withdraw request with your pool tokens, which creates a separate "withdraw-in-progress account".  the user would then call some ProcessWithdrawal with that account as many times as needed. For example, every time you call it, it could do a normal stake pool Withdraw instruction for just 1 validator for an amount of number_of_pool_tokens_to_withdraw / number_of_validators. And at the start of the next epoch, you could call a WithdrawFromInProgress instruction, which takes all of the stake accounts, and withdraws their lamports to somewhere else

> [7:42 PM] functional programmer: There is an edge case that COULD happen with slashing. Suppose that you are withdrawing 100 SOL from 2 VSAs (50 SOL each). This would be in two different ProcessWithdrawal calls. Suppose before the second ProcessWithdrawal call to validator 2, validator 2 got slashed. Then it's possible for that validator to not be able to service that 50 SOL withdrawal.


## Using a settlement period

Don't know much about this, because this is Jon's idea. A settlement period would allow us to batch transactions and settle everything in one go, which could be much more efficient. And it might resolve a lot of the other issues we've raised above. However, I have some worries:

- From our chat, it seems like the Solana Foundation is not keen to develop this, which means we'd have to fork and maintain it ourselves, which isn't great.
- It may introduce new edge cases.