FeeWrapper Contracts
This page provides an overview of the fee-wrapping smart contracts, which are built on top of DeFi project deposit functions to facilitate the collection and distribution of fees. The contracts are owned, allowing the owner to perform privileged operations such as setting the fee recipient or configuring the deposit parameters. The contracts act as an intermediary, facilitating deposits, deducting fees, transferring funds to the recipient, and not holding any funds.
Introduction
The FeeWrapper smart contracts allow wallets, dApps, and integrators to capture a fee on deposits made to vaults, lending protocols, and LSTs enabling them to monetize their services. Collected fees are split between a provider (StakeKit) and a specified fee recipient (the client). The contract owner can configure deposit contracts, manage whitelist statuses, and set fee rates.
We have two types of FeeWrapper contracts — FeeWrapper4626 which are applied to ERC-4626 compliant DeFi yields and Protocol Specific FeeWrapper contracts which are applied to all other non-ERC4626 compliant yields such as Aave V3 and Lido stETH liquid staking.
Contracts
FeeWrapper4626
Overview
The FeeWrapper4626 is built to capture fees on top of any ERC4626 compatible yield vault, such as YearnV3, Ethena, and Angle protocol
The contract maintains:
- A mapping of deposit contract configurations, each with a whitelist status and a fee rate.
- A mapping of fee configurations, each with a fee percentage and a fee recipient.
The contract allows for:
- Setting a provider fee recipient, which is the address that receives the provider fees.
- Configuring deposit contracts, including setting their whitelist status and fee rate.
- Setting the fee configuration for each deposit contract, including the fee percentage and the fee recipient.
The contract provides:
- A function for depositing tokens into the deposit contract and distributing fees.
- The deposit function checks that the deposit contract is whitelisted, calculates the fee, and transfers the fee and deposit amount to the appropriate addresses.
- The fee is split between the provider and the fee recipient according to the fee configuration.
- Helper functions for computing the fee and the fee split.
Functions
setProviderFeeRecipient
/**
* @notice Sets a new provider fee recipient
* @dev Only callable by the owner
* @param newProviderFeeRecipient The new provider fee recipient address
* @return The new provider fee recipient address
*/
function setProviderFeeRecipient(address newProviderFeeRecipient) external onlyOwner returns (address)
setDepositContractConfig
/**
* @notice Sets the configuration for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param whitelist Whether the contract is whitelisted
* @param fee The fee (in basis points) to deduct on deposit
* @return The configuration for the deposit contract
*/
function setDepositContractConfig(
address depositContract,
bool whitelist,
uint16 fee
)
external
onlyOwner
returns (DepositContractConfig memory)
setDepositContractWhitelist
/**
* @notice Sets the whitelist status for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param whitelist The whitelist status
* @return The whitelist status of the deposit contract
*/
function setDepositContractWhitelist(address depositContract, bool whitelist) external onlyOwner returns (bool)
setDepositContractFee
/**
* @notice Sets the fee for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param fee The fee (in basis points) to deduct on deposit
* @return The fee of the deposit contract
*/
function setDepositContractFee(address depositContract, uint16 fee) external onlyOwner returns (uint16)
setFeeConfig
/**
* @notice Sets the fee configuration for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
address depositContract,
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
setFeeRecipient
/**
* @notice Sets the fee recipient for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param feeRecipient The address that will receive the fee share
* @return The fee recipient of the deposit contract
*/
function setFeeRecipient(address depositContract, address feeRecipient) external onlyOwner returns (address)
setFeePercentage
/**
* @notice Sets the fee share percentage for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param feePercentage The fee in basis points
* @return The fee share percentage of the deposit contract
*/
function setFeePercentage(address depositContract, uint8 feePercentage) external onlyOwner returns (uint8)
deposit
/**
* @notice Deposits tokens into the deposit contract and distributes fees to provider and feeReecipient
* @param depositAddress The address of the deposit contract
* @param amount The amount of tokens to deposit
* @return shares The number of shares minted
*/
function deposit(address depositAddress, uint256 amount) external returns (uint256 shares)
Project Specific FeeWrapper Contract Functions
FeeWrapperAaveV3
setDepositContractConfig
/**
* @notice Sets the configuration for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param whitelist Whether the contract is whitelisted
* @param fee The fee (in basis points) to deduct on deposit
* @return The configuration for the deposit contract
*/
function setDepositContractConfig(
address depositContract,
bool whitelist,
uint16 fee
)
external
onlyOwner
returns (DepositContractConfig memory)
setFeeConfig
/**
* @notice Sets the fee configuration for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
address depositContract,
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
supply
/**
* @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* - E.g. User supplies 100 USDC and gets in return 100 aUSDC
* @param depositAddress The address of the deposit contract
* @param asset The address of the underlying asset to supply
* @param amount The amount to be supplied
* @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
**/
function supply(
address depositAddress
address asset,
uint256 amount,
address onBehalfOf,
uint16 referralCode
) external;
FeeWrapperCompoundV3
setDepositContractConfig
/**
* @notice Sets the configuration for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param whitelist Whether the contract is whitelisted
* @param fee The fee (in basis points) to deduct on deposit
* @return The configuration for the deposit contract
*/
function setDepositContractConfig(
address depositContract,
bool whitelist,
uint16 fee
)
external
onlyOwner
returns (DepositContractConfig memory)
setFeeConfig
/**
* @notice Sets the fee configuration for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
address depositContract,
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
supply
/**
* @notice Supply an amount of asset to the protocol
* @param depositAddress The address of the deposit contract
* @param asset The asset to supply
* @param amount The quantity to supply
*/
function supply(address depositAddress, address asset, uint amount) external
FeeWrapperYearnV2
setProviderFeeRecipient
/**
* @notice Supply an amount of asset to the protocol
* @param depositAddress The address of the deposit contract
* @param asset The asset to supply
* @param amount The quantity to supply
*/
function supply(address depositAddress, address asset, uint amount) external
setProviderFeeRecipient
/**
* @notice Sets a new provider fee recipient
* @dev Only callable by the owner
* @param newProviderFeeRecipient The new provider fee recipient address
* @return The new provider fee recipient address
*/
function setProviderFeeRecipient(address newProviderFeeRecipient) external onlyOwner returns (address)
setDepositContractConfig
/**
* @notice Sets the configuration for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param whitelist Whether the contract is whitelisted
* @param fee The fee (in basis points) to deduct on deposit
* @return The configuration for the deposit contract
*/
function setDepositContractConfig(
address depositContract,
bool whitelist,
uint16 fee
)
external
onlyOwner
returns (DepositContractConfig memory)
setDepositContractWhitelist
/**
* @notice Sets the whitelist status for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param whitelist The whitelist status
* @return The whitelist status of the deposit contract
*/
function setDepositContractWhitelist(address depositContract, bool whitelist) external onlyOwner returns (bool)
setDepositContractFee
/**
* @notice Sets the fee for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param fee The fee (in basis points) to deduct on deposit
* @return The fee of the deposit contract
*/
function setDepositContractFee(address depositContract, uint16 fee) external onlyOwner returns (uint16)
setFeeConfig
/**
* @notice Sets the fee configuration for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
address depositContract,
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
setFeeRecipient
/**
* @notice Sets the fee recipient for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param feeRecipient The address that will receive the fee share
* @return The fee recipient of the deposit contract
*/
function setFeeRecipient(address depositContract, address feeRecipient) external onlyOwner returns (address)
setFeePercentage
/**
* @notice Sets the fee share percentage for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param feePercentage The fee in basis points
* @return The fee share percentage of the deposit contract
*/
function setFeePercentage(address depositContract, uint8 feePercentage) external onlyOwner returns (uint8)
deposit
/**
* @notice Deposits tokens into the deposit contract and distributes fees to provider and feeReecipient
* @param depositAddress The address of the deposit contract
* @param amount The amount of tokens to deposit
* @return shares The number of shares minted
*/
function deposit(address depositAddress, uint256 amount) external returns (uint256 shares)
FeeWrapperEtherfi
setEnabled
/**
* @notice Sets if fee contract is enabled
* @dev Only callable by the owner
* @param enabled whether the fee contract is enabled or not
*/
function setEnabled(
bool enabled,
)
external
onlyOwner
setFeeConfig
/**
* @notice Sets the fee configuration
* @dev Only callable by the owner
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
deposit
/**
* @notice Send funds to the pool with optional referral parameter
* @param referral The referral address to use for the deposit (can be address(0) if none)
* @return mintedAmount the amount of eETH minted to the caller
*/
function deposit(address referral) external payable returns (uint256)
depositWithERC20
/**
* @notice Deposit Liquid Staking Token such as stETH and Mint eETH
* @param token The address of the token to deposit
* @param amount The amount of the token to deposit
* @param referral The referral address
* @return mintedAmount the amount of eETH minted to the caller (= msg.sender)
*/
function depositWithERC20(address token, uint256 amount, address referral) external returns (uint256)
FeeWrapperLidoLiquidETH
setEnabled
/**
* @notice Sets if fee contract is enabled
* @dev Only callable by the owner
* @param enabled whether the fee contract is enabled or not
*/
function setEnabled(
bool enabled,
)
external
onlyOwner
setFeeConfig
/**
* @notice Sets the fee configuration
* @dev Only callable by the owner
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
submit
/**
* @notice Send funds to the pool with optional referral parameter
* @dev This function is alternative way to submit funds. Supports optional referral address.
* @param referral The referral address to use for the deposit (can be address(0) if none)
* @return Amount of StETH shares generated
*/
function submit(address referral) external payable returns (uint256)
FeeWrapperRenzo
setEnabled
/**
* @notice Sets if fee contract is enabled
* @dev Only callable by the owner
* @param enabled whether the fee contract is enabled or not
*/
function setEnabled(
bool enabled,
)
external
onlyOwner
setFeeConfig
/**
* @notice Sets the fee configuration
* @dev Only callable by the owner
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
deposit
/**
* @notice Deposits an ERC20 collateral token into the protocol
* @param collateralToken The address of the collateral ERC20 token to deposit
* @param amount The amount of the collateral token to deposit in base units
* @param referralId The referral ID to use for the deposit (can be 0 if none)
*/
function deposit(IERC20 collateralToken, uint256 amount, uint256 referralId) external
depositETH
```
/**
* @notice Allows a user to deposit ETH into the protocol and get back ezETH
* @param referralId The referral ID to use for the deposit (can be 0 if none)
*/
function depositETH(uint256 referralId) external payable
```
FeeWrapperKelpDAO
setEnabled
/**
* @notice Sets if fee contract is enabled
* @dev Only callable by the owner
* @param enabled whether the fee contract is enabled or not
*/
function setEnabled(
bool enabled,
)
external
onlyOwner
setFeeConfig
/**
* @notice Sets the fee configuration
* @dev Only callable by the owner
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
depositAsset
/**
* @notice helps user stake LST to the protocol
* @param asset LST asset address to stake
* @param depositAmount LST asset amount to stake
* @param minRSETHAmountExpected Minimum amount of rseth to receive
* @param referralId referral id
*/
function depositAsset(
address asset,
uint256 depositAmount,
uint256 minRSETHAmountExpected,
string calldata referralId
) external
depositETH
/**
* @notice Allows user to deposit ETH to the protocol
* @param minRSETHAmountExpected Minimum amount of rseth to receive
* @param referralId referral id
*/
function depositETH(
uint256 minRSETHAmountExpected,
string calldata referralId
) external payable
FeeWrapperMorphoAave
setEnabled
/**
* @notice Sets if fee contract is enabled
* @dev Only callable by the owner
* @param enabled whether the fee contract is enabled or not
*/
function setEnabled(
bool enabled,
)
external
onlyOwner
setFeeConfig
/**
* @notice Sets the fee configuration
* @dev Only callable by the owner
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
supply
/**
* @notice Supplies underlying tokens to a specific market.
* @param poolToken The address of the market the user wants to interact with
* @param amount The amount of token (in underlying) to supply
*/
function supply(address poolToken, uint256 amount) external
FeeWrapperMorphoCompound
setEnabled
/**
* @notice Sets if fee contract is enabled
* @dev Only callable by the owner
* @param enabled whether the fee contract is enabled or not
*/
function setEnabled(
bool enabled,
)
external
onlyOwner
setFeeConfig
/**
* @notice Sets the fee configuration
* @dev Only callable by the owner
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
supply
/**
* @notice Supplies underlying tokens to a specific market.
* @param poolToken The address of the market the user wants to interact with
* @param amount The amount of token (in underlying) to supply
*/
function supply(address poolToken, uint256 amount) external
FeeWrapperStakeWiseV3
setDepositContractConfig
/**
* @notice Sets the configuration for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param whitelist Whether the contract is whitelisted
* @param fee The fee (in basis points) to deduct on deposit
* @return The configuration for the deposit contract
*/
function setDepositContractConfig(
address depositContract,
bool whitelist,
uint16 fee
)
external
onlyOwner
returns (DepositContractConfig memory)
setFeeConfig
/**
* @notice Sets the fee configuration for a deposit contract
* @dev Only callable by the owner
* @param depositContract The address of the deposit contract
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
address depositContract,
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
deposit
/**
* @notice Deposit ETH to the Vault
* @param depositAddress The address of the deposit contract
* @param receiver The address that will receive Vault's shares
* @param referrer The address of the referrer. Set to zero address if not used.
* @return shares The number of shares minted
*/
function deposit(address depositAddress, address receiver, address referrer) external payable returns (uint256 shares)
updatedStateAndDeposit
/**
* @notice Updates Vault state and deposits ETH to the Vault
* @param depositAddress The address of the deposit contract
* @param receiver The address that will receive Vault's shares
* @param referrer The address of the referrer. Set to zero address if not used.
* @param harvestParams The parameters for harvesting Keeper rewards
* @return shares The number of shares minted
*/
function updateStateAndDeposit(
address depositAddress,
address receiver,
address referrer,
IKeeperRewards.HarvestParams calldata harvestParams
) external payable returns (uint256 shares)
FeeWrapperBenqiLiquidAVAX
setEnabled
/**
* @notice Sets if fee contract is enabled
* @dev Only callable by the owner
* @param enabled whether the fee contract is enabled or not
*/
function setEnabled(
bool enabled,
)
external
onlyOwner
setFeeConfig
/**
* @notice Sets the fee configuration
* @dev Only callable by the owner
* @param feePercentage The percentage of the deposit contract fee to share with fee recipient
* @param feeRecipient the fee recipient
* @return The fee configuration for the deposit contract
*/
function setFeeConfig(
uint8 feePercentage,
address feeRecipient
)
external
onlyOwner
returns (FeeConfig memory)
submit
/**
* @notice Process user deposit, mints liquid tokens and increase the pool buffer
* @return Amount of sAVAX shares generated
*/
function submit() public payable returns (uint)
Security Considerations
- Only the contract owner can update the fee percentage and other configurations by implementing the onlyOwner modifier.
- Perform thorough testing and Trail of Bits audit before deploying to the mainnet.
- The contracts are not designed to be behind a proxy, for simplicity.
- The contracts will only act as intermediaries, facilitating deposits, deducting fees, transferring funds to the recipient, and not holding any funds.
- Regularly review and deploy new contract versions to address any discovered vulnerabilities.
Updated 6 months ago