Skip to main content
FeeCollector receives protocol revenue and splits it into a reserve and a treasury. Interest cash arrives from Stockline on repay; liquidation fees arrive as seized stock tokens and are sold for USDG with sweepCollateral. Unallocated USDG fills the reserve up to a target of 5% of pool borrows, then flows to the treasury. Anyone can spend the reserve on pool bad debt and burn treasury USDG into STK within an epoch budget. FeeCollector lets you:
  • Allocate fresh USDG into reserve, then treasury
  • Cover pool bad debt from the reserve
  • Buy and burn STK with treasury USDG inside the epoch budget
  • Sell seized collateral for USDG along its zap route
  • Credit reserve and treasury directly (used by CreatorFeeRouter)
  • Read the reserve, treasury, target, and epoch state
Addresses per network. Every address is also on Addresses. The source code is src/core/FeeCollector.sol on GitHub. The ABI is /abis/FeeCollector.json.

Write methods

notifyInterest

Records that amount of reserve-factor interest has accrued. Only Stockline can call it. This is a counter; the cash arrives later on repay.
Core only.
Input parameters

notifyLiquidationFee

Records that amount of seized collateral arrived as the protocol’s liquidation share. Only Stockline can call it.
Core only.
Input parameters

credit

Pulls toReserve + toTreasury USDG from the caller and credits the two buckets directly, skipping the target waterfall. Permissionless. CreatorFeeRouter uses it for the 40/30 split. Reverts with ZeroAmount when both are zero.
The caller must approve FeeCollector for the total. USDG sent here belongs to the protocol.
Direct credits skip the allocate waterfall so a Pons split can raise reserve even when the 5% target is already full.
Input parameters

setReserveTargetPct

Sets the reserve target as a share of pool.borrowed(). Owner only. Reverts with InvalidWad above 1e18.
Owner (timelock) only.
Input parameters

setBurnEpoch

Sets the length of each buy-and-burn epoch. Owner only. Reverts with InvalidEpoch outside [1 day, 90 days].
Owner (timelock) only.
Input parameters

allocate

Moves any USDG not yet assigned to reserve or treasury: first fills the reserve up to reserveTarget, then sends the rest to the treasury. Permissionless. Emits Allocated only when something moved.

coverBadDebt

Spends up to amount of the reserve into USDGPool through restore, making suppliers whole after a write-off. Permissionless. Allocates first. Reverts with ZeroAmount when amount is 0 or the reserve is empty.
This does not check that the pool actually had bad debt. It always increases pool cash and the sUSDG share price.
Input parameters

buyAndBurn

Swaps amount treasury USDG along the buy-and-burn route and sends the output token to the dead address. Permissionless. Reverts with EpochBudgetExceeded above the unused epoch budget, InsufficientTreasury above the treasury balance, CapExceeded above maxPerCall, and InvalidRoute if the route does not start with USDG.
Each epoch’s budget is 20% (2000 bps, fixed) of the treasury at roll time. The first epoch after deployment has a budget of 0, so burns can start only after the first roll. Slippage is checked against the router’s TWAP quote.
Input parameters

sweepCollateral

Sells the whole balance of a seized collateral token for USDG using its zap route, then allocates. Permissionless. Reverts with InvalidRoute for USDG or a route that does not end in USDG, NotAllowed if the token has no allowed route, and ZeroAmount when the balance is 0. Input parameters

Read methods

reserveTarget

Returns the reserve the waterfall fills before the treasury: pool.borrowed() * reserveTargetPct / 1e18. Return values

unallocated

Returns USDG held here that is not yet assigned to reserve or treasury. Return values

Events

Allocated

Fires when unallocated USDG moves into reserve and treasury.

Credited

Fires when someone credits reserve and treasury directly.

ReserveTargetPctSet

Fires when the reserve target share changes.

BurnEpochSet

Fires when the epoch length changes.

EpochRolled

Fires when a new burn epoch starts, with its start and budget.

Covered

Fires when reserve USDG is sent to the pool to cover bad debt.

BuyAndBurn

Fires when treasury USDG is swapped and the output is burned.

CollateralSwept

Fires when seized collateral is sold for USDG.

Errors

ZeroAddress

A constructor address was zero, or the registry has no DEX router.

NotCore

Only Stockline can notify fees.

NotOwner

Only the timelock can change the target or epoch.

ZeroAmount

An amount was zero or nothing was available.

InvalidWad

The reserve target share is above 1e18.

InsufficientTreasury

The burn amount exceeds the treasury.

CapExceeded

The burn amount exceeds maxPerCall.

InvalidRoute

The swap route is missing, too short, or has the wrong endpoints.

NotAllowed

The token has no allowed zap route.

InvalidEpoch

The epoch length is outside 1 to 90 days.

EpochBudgetExceeded

The burn amount exceeds the unused budget of the current epoch.