Token System Specifications
Overview
fUSD
Stablecoin
Entry asset, 1:1 backed by approved stablecoins
ERC20 (Upgradeable)
sfUSD
Share Token
Yield-bearing staked position
ERC20 (Upgradeable)
Both tokens are upgradeable via the UUPS (Universal Upgradeable Proxy Standard) pattern, allowing the protocol to evolve while preserving user balances and state.
fUSD : Frgmnt Stable Asset
Token Details
Name
fUSD
Symbol
fUSD
Decimals
18
Standard
ERC20Upgradeable
Upgrade Pattern
UUPS
Minting Mechanism
fUSD is minted through deposits of approved stablecoins. The mint amount is calculated using oracle-sourced USD prices:
fUSD Minted = Deposit Amount × Oracle PriceApproved Assets: The protocol maintains a whitelist of accepted stablecoins (e.g., USDC, DAI, USDT). Each asset must be explicitly approved through governance before it can be used for minting.
Deposit Flow
User approves stablecoin spending for fUSD contract
User calls deposit with approved stablecoin
Contract validates asset is on the allowlist
Oracle provides current USD price for the asset
Deposit transfers to the sfUSD sink (staking pool)
fUSD minted to user at equivalent USD value
Access Control
DEFAULT_ADMIN_ROLE
Grant and revoke other roles
GOVERNANCE_ROLE
Manage oracle, sfUSD sink, allowed assets, authorize upgrades
EMERGENCY_ROLE
Pause/unpause deposits
Security Features
Reentrancy Guard : Prevents recursive call exploits
Pausable : Emergency pause capability for deposits
Role-Based Access : Granular permission system
sfUSD : Staked FUSD
Token Details
Name
Staked fUSD (configurable)
Symbol
sfUSD (configurable)
Decimals
18
Standard
ERC20Upgradeable
Upgrade Pattern
UUPS
Share Pricing
sfUSD uses a share-based model where the token price represents the value of one sfUSD share in terms of underlying assets:
As the pool generates yield, the token price increases, meaning each sfUSD share is worth more over time.
Staking (fUSD → sfUSD)
When staking fUSD, shares are minted based on the current token price:
Entry Fee: Applied as additional shares minted to the manager; not deducted from the user's deposit. This means users receive shares worth their full deposit amount.
Unstaking (sfUSD → Assets)
Immediate Mode: Users burn sfUSD and receive proportional pool assets instantly.
Exit Fee: Applied as shares burned from the user before calculating withdrawal amount.
Queued Mode: For pools with queued withdrawals enabled:
requestWithdraw(shares)Lock shares, receive request IDManager calls
finalizeWithdraw(requestId)Burns shares, locks fUSD amountclaimWithdraw(requestId)User receives finalized fUSD
Yield Mechanics
sfUSD implements a dual yield system that separates principal appreciation from harvestable rewards:
1. Token Price Growth (Principal Appreciation)
The core share price increases as the pool generates value:
This happens automatically as:
Strategy positions generate PnL
The pool collects fees from other activities
External yield sources accrue to the pool
2. Harvestable Yield Accumulator
A separate mechanism converts token price growth into claimable fUSD rewards using a global accumulator pattern:
yieldPerShare
Cumulative fUSD yield per share (scaled 1e18)
lastTokenPriceForYield
Token price checkpoint for yield calculation
userYields[address].rewardDebt
User's last yieldPerShare checkpoint
userYields[address].claimable
Accumulated fUSD pending harvest
How it works:
On every user interaction (stake, unstake, harvest), the updateFeesAndYieldFor modifier:
Mints any pending manager fees
Calculates current token price
If price increased since
lastTokenPriceForYield:For the specific user:
Harvesting:
Users call harvest() to claim accumulated fUSD without touching their sfUSD shares:
This design means users can choose to:
Hold sfUSD and let both principal and harvestable yield compound
Harvest regularly to realize fUSD gains while maintaining their staked position
Unstake to exit entirely with their proportional share of pool assets
Fee Minting
Performance and management fees are minted as new sfUSD shares to the manager and DAO:
Performance Fee
Percentage of token price growth since tokenPriceAtLastFeeMint
Management Fee
Time-weighted streaming fee based on lastFeeMintTime
The DAO receives a percentage of total fees (configured in factory), remainder goes to the manager. This dilutes all holders proportionally rather than transferring from individual accounts.
Withdrawal Modes
Immediate
Direct burn-for-assets, subject to liquidity and cooldown
Queued
Lido-style: lock shares → manager finalizes → user claims
Pool managers can toggle between modes based on pool strategy requirements.
Queued Withdrawal Flow:
Request (
requestWithdraw): User locks sfUSD shares, exit fee taken upfront in sharesFinalize (
finalizeWithdraw): Manager burns the locked shares, calculates fUSD amount at current priceClaim (
claimWithdraw): User receives the finalized fUSD amount
This pattern allows managers to handle illiquid positions gracefully without forcing immediate liquidation.
Pool Manager Logic Integration
Both tokens integrate with PoolManagerLogic for:
Asset Management
Valuation
Fee Configuration
Fee Changes: Fee increases require an announcement period before they can be committed, protecting users from sudden changes:
announceFeeIncrease()Propose new feesWait for timelock period
commitFeeIncrease()Apply new feesOr
renounceFeeIncrease()Cancel proposal
Access Control
Pools can be configured as private (whitelist only) or public, with optional NFT-gated access.
Guard System
All external protocol interactions are validated through a two-layer guard system managed by the Governance contract:
Contract Guards
Assigned per external contract address (e.g., Aave, Uniswap routers). When sfUSD calls execTransaction():
The guard's
txGuard()function parses the calldataReturns a
txType(transaction classification) andisPublicflagIf
txType > 0, the transaction is allowedIf not public, only manager or trader can execute
Available contract guards include:
AaveLendingPoolGuardV2/V3Deposit, withdraw, borrow, repayUniswapV2RouterGuardSwaps and liquidity operationsUniswapV3RouterGuardV3 swaps with path validationMorphoContractGuardMorpho lending operationsCompoundV3CometContractGuardCompound V3 supply/withdraw
Asset Guards
Assigned per asset type ID. Handle balance calculation and withdrawal processing for different asset classes:
Transaction Execution Flow
Post-Transaction Hooks
Guards implementing ITxTrackingGuard can run logic after transaction execution:
Uniswap V3 NFT Guard: Tracks minted/burned NFT position IDs
Aave V3 L2 Guard: Validates health factor stays above 1.01
Events
fUSD Events
Deposit(user, asset, amount, fusdMinted)
User deposited stablecoins for fUSD
sfUSD Events
Stake(user, fusdAmount, mintedShares, entryFeeShares)
User staked fUSD
Harvest(user, fusdAmount)
User claimed yield
WithdrawRequested(id, user, sharesLocked, exitFeeShares)
Queued withdrawal initiated
WithdrawFinalized(id, fusdAmount)
Manager finalized withdrawal
WithdrawClaimed(id, user, fusdAmount)
User claimed withdrawal
ManagerFeeMinted(pool, manager, available, daoFee, managerFee, tokenPrice)
Fees minted
TransactionExecuted(pool, manager, txType, time)
Guarded transaction completed
Security Considerations
Reentrancy Protection
Both tokens implement ReentrancyGuardUpgradeable on all state-changing external functions.
Cooldown Mechanisms
sfUSD implements a weighted cooldown system to prevent flash-loan exploits:
lastDeposit[address]
Timestamp of user's last stake
lastExitCooldown[address]
Calculated cooldown duration for user
Cooldown Calculation:
When staking, the cooldown is weighted based on new vs existing position size:
Transfer Restriction:
The _update() hook blocks transfers if cooldown is active, unless the recipient is whitelisted:
Upgrade Safety
Storage layout must be preserved across upgrades:
Never remove or rename existing state variables
Append new variables before
__gapMaintain
__gaparray for future expansion
Decimal Handling
All calculations account for varying decimals across stablecoins. Oracle prices normalize to 18 decimals for consistent math.
Contract Addresses
Addresses will be published here after mainnet deployment.
fUSD Proxy
BASE - 8453
TBD
sfUSD Proxy
BASE - 8453
TBD
PoolManagerLogic
BASE - 8453
TBD
Governance
BASE - 8453BASE - 8453
TBD
Integration Guide
Reading Token Price
Calculating Share Value
Checking Claimable Yield
Staking fUSD
Harvesting Yield
Unstaking (Immediate Mode)
Last updated
