const BpsDenominator
BpsDenominator is the fee basis: fees are bps/BpsDenominator of the deposited amount.
Package feeledger is a pure accounting primitive for realms that hold coins on behalf of users and charge an explicit...
Package feeledger is a pure accounting primitive for realms that hold coins on behalf of users and charge an explicit protocol fee on deposits. It tracks per-account balances, the sum of user liabilities, and a separately-accrued fee pot. It never touches coins itself: the importing realm moves coins and drives this ledger, keeping the two in lock-step so that
1coins held by realm == UsersTotal() + FeesAccrued() + surplus
where surplus is coins pushed to the realm outside the ledger's flow (always >= 0, and 0 if every coin movement goes through the ledger).
Fee model:
All failures are returned as errors and leave the ledger COMPLETELY UNCHANGED; callers in realms typically wrap calls so an error panics and aborts the transaction. Must* wrappers are provided and are the only functions in this package that panic.
The ledger is address-agnostic: accounts are non-empty strings. Realms normally use address.String().
BpsDenominator is the fee basis: fees are bps/BpsDenominator of the deposited amount.
1var (
2 ErrEmptyAccount = errors.New("feeledger: empty account key")
3 ErrInvalidAmount = errors.New("feeledger: amount must be positive")
4 ErrInvalidBps = errors.New("feeledger: fee bps out of range")
5 ErrInsufficient = errors.New("feeledger: insufficient balance")
6 ErrOverflow = errors.New("feeledger: int64 overflow")
7)Errors returned by Ledger operations.
FeeFor returns the fee charged on amount at bps, using the ledger's rounding rule: floor(amount * bps / BpsDenominator). It is a pure preview — no state is read or written beyond validation against BpsDenominator (NOT the ledger cap; use it to inspect any policy). amount must be >= 0 and bps in [0, BpsDenominator].
MustNew is New but panics on error.
New returns an empty ledger that rejects deposit fees above maxFeeBps. maxFeeBps must be in [0, BpsDenominator].
Ledger tracks per-account balances, their sum (user liabilities), and separately-accrued protocol fees. The zero value is not usable; construct with New.
Accounts returns the number of accounts with a non-zero balance.
BalanceOf returns account's balance, or 0 if absent.
1func (l *Ledger) Deposit(account string, amount, feeBps int64) (credited, fee int64, err error)Deposit credits account with amount minus the fee at feeBps, accruing the fee to the fee pot. Returns the credited amount and the fee (credited + fee == amount always). Fails with ErrEmptyAccount, ErrInvalidAmount (amount <= 0), ErrInvalidBps (feeBps outside [0, MaxFeeBps]), or ErrOverflow if the account balance or total liabilities would leave int64 range. On error nothing is modified.
FeesAccrued returns the fee pot: charged but not yet withdrawn.
Iterate calls fn for each account in sorted order with its balance. Iteration stops early when fn returns true.
Liabilities returns UsersTotal() + FeesAccrued() — everything the importing realm owes. Deposit guarantees this sum fits in int64.
MaxFeeBps returns the ledger's hard fee cap.
MustDeposit is Deposit but panics on error.
MustWithdraw is Withdraw but panics on error.
UsersTotal returns the sum of all account balances (user liabilities).
Withdraw debits amount from account. Fails with ErrEmptyAccount, ErrInvalidAmount (amount <= 0), or ErrInsufficient if the balance is smaller than amount. A balance drained to zero is removed from storage. On error nothing is modified.
WithdrawAll drains account's entire balance and returns it. Returns (0, nil) if the account holds nothing. Fails only with ErrEmptyAccount.
WithdrawFees drains the accrued fee pot and returns the amount (0 if nothing has accrued). Never fails.