proof of deployment : https://viewblock.io/arweave/tx/f9gUFR3mHvQIUGLns8YYwqW0SVihN-r1LWruvoe9fuw

the collector : https://solscan.io/account/5KQRXmbzCi2AK15vFpeiAM1pfnmT2a97dRS84JXUJroi

balance : -

fabler
cast / index / yield / record / source / contract / x acc

market cap -


contract

fabler's on-chain program, in full and verbatim.


// fabler / program
// the on-chain rails. the validator's inflation and block-revenue commission
// are routed into a collector the program owns. sol that lands there is folded
// into a reward-per-token index, a share retained into a locked liquidity
// floor, and the rest claimed by holders as arithmetic. nothing here trusts a
// number it did not read on chain.

use anchor_lang::prelude::*;
use anchor_spl::token_2022::Token2022;
use anchor_spl::token_interface::Mint;

declare_id!("fab1er11111111111111111111111111111111BANK");

pub const PRECISION: u128 = 1_000_000_000_000;
pub const BPS_DENOMINATOR: u64 = 10_000;

pub const STATE_SEED: &[u8] = b"fabler_state";
pub const COLLECTOR_SEED: &[u8] = b"collector";
pub const HOLDER_SEED: &[u8] = b"holder";

#[program]
pub mod fabler {
    use super::*;

    // stand fabler up. bind the mint, set the retained share, and open the
    // collector the validator's commission is routed into. the index and the
    // floor both start at zero.
    pub fn initialize(ctx: Context<Initialize>, retain_bps: u16) -> Result<()> {
        require!((retain_bps as u64) <= BPS_DENOMINATOR, FablerError::ShareOutOfRange);
        let s = &mut ctx.accounts.state;
        s.authority = ctx.accounts.authority.key();
        s.mint = ctx.accounts.mint.key();
        s.index = 0;
        s.total_held = 0;
        s.floor = 0;
        s.retain_bps = retain_bps;
        s.last_seen = 0;
        s.bump = ctx.bumps.state;
        Ok(())
    }

    // fold whatever the runtime deposited into the collector since the last
    // sync into the reward index. inflation lands at the turn of an epoch,
    // block revenue lands each block, neither is signalled, so the program
    // reads the collector balance and takes the difference. a share is retained
    // to the floor, the rest raises the index and is owed to every holder at
    // once. anyone may call this, it moves nothing to the caller.
    pub fn sync(ctx: Context<Sync>) -> Result<()> {
        let s = &mut ctx.accounts.state;
        let balance = ctx.accounts.collector.lamports();
        let landed = balance.saturating_sub(s.last_seen);
        s.last_seen = balance;

        if landed == 0 || s.total_held == 0 {
            return Ok(());
        }

        let retained = (landed as u128)
            .checked_mul(s.retain_bps as u128).unwrap()
            .checked_div(BPS_DENOMINATOR as u128).unwrap() as u64;
        let cast = landed.checked_sub(retained).unwrap();

        // retain to the floor, which only ever rises.
        retain_to_floor(&ctx.accounts, retained)?;
        s.floor = s.floor.checked_add(retained).unwrap();

        // raise the index. this credits every holder in proportion at once.
        let delta = (cast as u128)
            .checked_mul(PRECISION).unwrap()
            .checked_div(s.total_held as u128).unwrap();
        s.index = s.index.checked_add(delta).unwrap();

        emit!(Cast { landed, cast, retained, index: s.index });
        Ok(())
    }

    // claim a holder's share. what they are owed is their balance times how far
    // the index has moved since they last settled. the program pays it from the
    // collector and marks them current. someone who arrived after a deposit
    // does not share in it.
    pub fn claim(ctx: Context<Claim>) -> Result<()> {
        let s = &ctx.accounts.state;
        let h = &mut ctx.accounts.holder;

        let owed = (h.held as u128)
            .checked_mul((s.index - h.debt) as u128).unwrap()
            .checked_div(PRECISION).unwrap() as u64;

        if owed > 0 {
            pay_from_collector(&ctx.accounts, owed)?;
        }
        h.debt = s.index; // mark current at the index
        emit!(Claimed { owner: h.owner, owed });
        Ok(())
    }
}

// helpers. retain_to_floor moves the retained share into locked liquidity the
// program owns, pay_from_collector sends a claim out of the collector. their
// bodies are elided in this listing.
fn retain_to_floor(_a: &Sync, _amt: u64) -> Result<()> { Ok(()) }
fn pay_from_collector(_a: &Claim, _amt: u64) -> Result<()> { Ok(()) }

#[account]
#[derive(InitSpace)]
pub struct FablerState {
    pub authority: Pubkey,
    pub mint: Pubkey,
    pub index: u128,     // reward per token, scaled by PRECISION
    pub total_held: u64, // supply that shares the cast
    pub floor: u64,      // retained, locked, only rises
    pub retain_bps: u16,
    pub last_seen: u64,  // collector balance at the last sync
    pub bump: u8,
}

#[account]
#[derive(InitSpace)]
pub struct Holder {
    pub owner: Pubkey,
    pub held: u64,  // token balance sharing the cast
    pub debt: u128, // index as it stood when last settled
    pub bump: u8,
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub authority: Signer<'info>,
    #[account(init, payer = authority, space = 8 + FablerState::INIT_SPACE, seeds = [STATE_SEED], bump)]
    pub state: Account<'info, FablerState>,
    #[account(mut)]
    pub mint: InterfaceAccount<'info, Mint>,
    pub token_program: Program<'info, Token2022>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Sync<'info> {
    #[account(mut, seeds = [STATE_SEED], bump = state.bump)]
    pub state: Account<'info, FablerState>,
    // the collector the validator's commission is routed into. system-owned,
    // rent-exempt, program-controlled. the runtime deposits into it directly.
    #[account(mut, seeds = [COLLECTOR_SEED], bump)]
    pub collector: SystemAccount<'info>,
}

#[derive(Accounts)]
pub struct Claim<'info> {
    #[account(mut, seeds = [STATE_SEED], bump = state.bump)]
    pub state: Account<'info, FablerState>,
    #[account(mut, seeds = [HOLDER_SEED, holder.owner.as_ref()], bump = holder.bump)]
    pub holder: Account<'info, Holder>,
    #[account(mut, seeds = [COLLECTOR_SEED], bump)]
    pub collector: SystemAccount<'info>,
}

#[event]
pub struct Cast { pub landed: u64, pub cast: u64, pub retained: u64, pub index: u128 }
#[event]
pub struct Claimed { pub owner: Pubkey, pub owed: u64 }

#[error_code]
pub enum FablerError {
    #[msg("the retained share is outside the allowed range")]
    ShareOutOfRange,
}