Profit Distribution
Every FX swap's total profit (Spread + Platform Fee) is distributed atomically in the same on-chain transaction. Split ratios (50/30/20) are stored in the ProtocolConfig contract. Fee amounts (fixed fee, variable fee, base spread) are resolved from the Volume-Tiered Fee Schedule which is configured per corridor per transaction size in the database.
1. The Configurable Split
| Recipient | Default | Config Key | Description |
|---|---|---|---|
| Protocol Treasury (KF) | 50% | KF_SHARE_PCT | Protocol revenue. Not shared with LPs. Acts as insurance — absorbs all losses by burning kUSD. |
| Transaction LP Reward | 30% | TXN_LP_SHARE_PCT | Distributed as kUSD to LPs whose currency pools were DIRECTLY INVOLVED in the swap corridor. Triggers updateIndex() on Vault Contract. |
| Global Fee Pool | 20% | GLOBAL_LP_SHARE_PCT | Distributed as kUSD to LPs whose currency pools were NOT involved in the swap corridor. Accumulated in Fee Contract; distributed via periodic harvest. |
KF_SHARE_PCT + TXN_LP_SHARE_PCT + GLOBAL_LP_SHARE_PCT must always equal 100%. The ProtocolConfig contract enforces this on any parameter update.
2. Transaction LP vs. Global LP Classification
For every FX swap, all active LP pools are classified into two groups based on the swap corridor:
| Swap Corridor | Transaction LPs (receive TXN share) | Global LPs (receive GLOBAL share) |
|---|---|---|
| USD → IDR | LP-USD, LP-IDR | LP-MYR, LP-SGD |
| MYR → IDR | LP-MYR, LP-IDR | LP-USD, LP-SGD |
| USD → SGD | LP-USD, LP-SGD | LP-IDR, LP-MYR |
| MYR → IDR (synthetic) | LP-MYR, LP-IDR | LP-USD, LP-SGD |
For MYR→IDR swaps routed through USD internally (synthetic rate), Transaction LPs are LP-MYR and LP-IDR — the user-facing source and destination pools. LP-USD is classified as Global LP even though USD is used as an internal pivot. The pivot is a routing mechanism, not a user-facing corridor.
3. Distribution Within Each Bucket
Within the Transaction and Global buckets, profit is distributed proportionally by each eligible LP's effective weight, which combines equity and class multiplier.
LP Equity
Equity_i(t) = DepositValueUSD_i + AccumulatedProfitkUSD_i(t−1)
DepositValueUSD_i= USD value of the LP's single-currency deposit (using oracle for conversion).AccumulatedProfitkUSD_i(t−1)= all kUSD profits minted to the LP up to end of previous day.
This creates a compounding effect: yesterday's kUSD rewards increase today's equity, which increases today's share of distributions.
Effective Weight (Class A/B Modifier)
EffectiveWeight_i = Equity_i × ClassA_fee_tier_multiplier_i
Class B LPs always have a multiplier of 1.0× (standard rate). Class A LPs have a configurable per-partner multiplier set at onboarding (e.g., 0.3× for stablecoin issuers, 0.8× for institutional funds).
Per-LP Profit
Profit_i = BucketProfit × (EffectiveWeight_i / Σ EffectiveWeight_eligible)
The profit is minted as kUSD and added to the LP's accumulated profit, increasing their equity for the next distribution cycle.
Class A/B Index Update
When the LP share reaches a specific currency pool, it updates the appropriate kToken index:
| LP Class | Index Updated | Feed Sources |
|---|---|---|
| Class A (FX-Only) | kXXX-fx Vault → updateIndex(classA_share) | FX swap fees only (at custom tier rate) |
| Class B (Full) | kXXX-full Vault → updateIndex(classB_share) | FX swap fees (standard rate) + Yield profits |
4. Loss Handling
| Rule | Behaviour |
|---|---|
| LP Protection | LP equities never decrease. Losses are never distributed to LPs. This is an absolute protocol guarantee. |
| KF Absorbs Loss | The Protocol Treasury (KF) absorbs losses by burning its kUSD balance. KF functions as the protocol's insurance layer. |
| KF Depletion | If KF kUSD reaches zero, losses are booked as protocol debt. No LP impact. Ops is alerted for intervention. |
| No Distribution on Loss | When a swap day results in net loss, there is no profit distribution. Only the KF burn occurs. |