Fee Auction
The Fee Auction facilitates permissionless Dutch auctions where collected protocol fees are sold to the winning bidder. The proceeds are sent to the Fee Receiver to convert to cUSD and distribute to stcUSD holders. The Fee Auction module provides an efficient and transparent way to distribute accumulated fees to participants while ensuring fair price discovery through time-based price decay.
Mechanics
Overview of Operations
Interest Harvesting: Interest Harvester realizes accumulated interest and sends it to Fee Auction
Dutch Auction: Fee Auction sells accumulated assets via a Dutch auction mechanism
Fee Distribution: Fee Receiver collects cUSD from auction sales and distributes to stcUSD token holders

Dutch Auction Mechanics
Admin sets a starting price (in cUSD) and the duration of auctions.
The price decays linearly over time (up to 90% or until minimum price is reached) until a winning bidder makes a purchase. All accumulated fees are distributed to the buyer.
The purchase triggers the start of the next auction, where the starting price is set to be double the settled price.
Key Auction Parameters
Starting Price: Initial price set by admin for each auction (in cUSD)
Duration: Auction duration set to 24 hours by default
Minimum Start Price: Minimum starting price set to 100 cUSD
Payment Token: cUSD is used as the payment token for all auctions
Recipient: Fee Receiver contract receives all auction proceeds
Price Multiplier: New auction starts at 2x the settled price of the previous auction
Architecture
The Fee Auction system consists of three main components:
FeeAuction Contract - Facilitates Dutch auction mechanism for selling fees
FeeReceiver Contract - Manages fee distribution to stakeholders
Gelato Automations - Automates harvesting interest and distributing rewards
Fee Auction
The FeeAuction contract implements a Dutch auction mechanism for selling accumulated yield.
Core Functions
buy: Allows permissionless purchase of accumulated fees at current auction price
function buy(
uint256 _maxPrice,address[] calldata _assets, uint256[] calldata _minAmounts, address _receiver, uint256 _deadline
) external;_maxPrice: Maximum price willing to pay_assets: Array of assets to purchase_minAmounts: Minimum amounts to purchase for each asset_receiver: Address to receive the purchased assets_deadline: Deadline for the auction purchase
Admin Functions
setStartPrice: Sets the starting price for the current auction
function setStartPrice(uint256 _startPrice) external checkAccess(this.setStartPrice.selector)setDuration: Sets the duration for future auctions
function setDuration(uint256 _duration) external checkAccess(this.setDuration.selector)setMinStartPrice: Sets the minimum starting price for future auctions
function setMinStartPrice(uint256 _minStartPrice) external checkAccess(this.setMinStartPrice.selector)setPaymentToken: Sets the payment token for the auction
function setPaymentToken(address _paymentToken) external checkAccess(this.setPaymentToken.selector)Fee Receiver
The Fee Receiver distributes fees collected from the auction to stakeholders. The protocol can take a percentage of the accumulated yield for protocol treasury. The protocol fee is currently configured to 0.
Core Functions
distribute: Distributes fees to staked cap token holders
function distribute() external;The notify function is called when the vesting period is complete. The vesting period is configured to 24 hours.
Admin Functions
setCapToken: Sets the Cap token address
function setCapToken(address _capToken) external checkAccess(this.setCapToken.selector)setStakedCapToken: Sets the staked Cap token address
function setStakedCapToken(address _stakedCapToken) external checkAccess(this.setStakedCapToken.selector)setProtocolFeePercentage: Sets protocol fee percentage
function setProtocolFeePercentage(uint256 _protocolFeePercentage) external checkAccess(this.setProtocolFeePercentage.selector)setProtocolFeeReceiver: Sets protocol fee recipient
function setProtocolFeeReceiver(address _protocolFeeReceiver) external checkAccess(this.setProtocolFeeReceiver.selector)Gelato Integrations
Gelato is used in the Fee Auction to automate yield harvesting and fee distribution via CapInterestHarvester and CapNotify respectively.
CapInterestHarvester
harvestInterest: Harvests yields from multiple sources and triggers fee distribution
function harvestInterest() external;Harvests yields from many sources via the harvestInterest function. The function executes the following:
Fractional Reserve Harvesting: Calls the Harvester contract to realize yields from FR strategies
Lender Interest Claiming: Claims accumulated interest from lending operations
Flash Loan Optimization: Uses Balancer flash loans to efficiently buy interest from fee auction
Fee Distribution: Triggers distribution of collected fees
Execution Conditions:
Time-based: Execute if 24 hours have passed since last harvest
Profit-based: Execute if minting cUSD and buying interest is profitable
Gas Optimization: Only execute when profitable to cover gas costs
CapNotify
notify: Automates fee distribution to stcUSD holders
function notify() external;Execution Conditions:
Vesting Period: Only execute after lock duration has passed
Time-based: Respect profit vesting schedules
Staked CAP: Ensure proper distribution to token holders
Data Structures
FeeAuctionStorage
The FeeAuctionStorage stores auction configuration and state information.
struct FeeAuctionStorage {
uint256 startPrice; // Starting price for current auction
uint256 duration; // Auction duration in seconds
uint256 minStartPrice; // Minimum starting price
address paymentToken; // Payment token (cUSD)
address recipient; // Fee receiver address
uint256 auctionStartTime; // Current auction start time
uint256 currentPrice; // Current auction price
bool auctionActive; // Whether auction is active
}FeeReceiverStorage
The FeeReceiverStorage stores fee distribution configuration.
struct FeeReceiverStorage {
address capToken; // Cap token address
address stakedCapToken; // Staked cap token address
uint256 protocolFeePercentage; // Protocol fee percentage
address protocolFeeReceiver; // Protocol fee recipient
uint256 vestingPeriod; // Vesting period in seconds
uint256 lastDistributionTime; // Last distribution timestamp
uint256 totalFeesDistributed; // Total fees distributed
}Last updated