If I wanted to do some funds distribution from a Solana program, what would be the best way to do so structurally?
Say I wanted to maintain some distribution endpoints. E.g.:
treasury
,treasury_pct
community
,com_pct
This is what I came up with:
Setup
pub enum VaultLabel {
None,
Treasury,
Community,
Operations,
}
#[account]
pub struct Vault {
pub bump: u8,
pub pct: u8,
pub label: VaultLabel,
}
Then I create an instruction context that initialises all the required vaults. Each vault just becomes a global PDA with a predefined seed, where the PDA can own some token accounts:
pub struct VaultCreate<'info> {
#[account(
init,
seeds = [SEED_TREASURY],
bump,
payer = payer,
space = Vault::LEN,
)]
pub treasury: Account<'info, Vault>,
#[account(
init,
seeds = [SEED_COMMUNITY],
bump,
payer = payer,
space = Vault::LEN,
)]
pub community: Account<'info, Vault>,
...
}
pub struct VaultCreateParams {
pub percentages: {treasury: u8, community: u8, operations: u8},
}
Note
payer
can be restricted to be an admin of a specific pubkey.VaultCreateParams
add up to precisely 100.Distribution logic
If you have an instruction for payment, you could incorporate the distribution logic therein (of course, this depends on your particular use-case)
remaining_accounts
. Deserialize with Account::<'info, Vault>
and Account::<'info, TokenAccount>::try_from
. Combining with address lookup tables and versioned transactions, the extra account overhead is negligible, especially when those accounts remain constantvault.pct