Authors
Summary
Goldfinch should allow FIDU-USDC Curve LP positions to be staked for GFI liquidity mining rewards.
GFI rewards would come from the existing distribution parameters to the Senior Pool Liquidity Mining program, and only the FIDU portion of the Curve LP position would be eligible for GFI rewards. This would help create a liquid secondary market of FIDU and USDC, which (a) reduces the friction of entering and exiting Goldfinch Senior Pool positions, (b) results in more USDC staying in the Senior Pool, and (c) allows people to get exposure to the Goldfinch Senior Pool by simply purchasing FIDU on Curve.
Motivation
When Goldfinch Liquidity Providers deposit USDC into the Senior Pool they receive FIDU, which is an ERC20 token that tracks their deposit and the interest payments accrued. Currently, if a user wants to remove their Senior Pool deposit, they can exchange FIDU for USDC on Goldfinch, but withdrawals are limited to the unutilized USDC in the Senior Pool and incurs a 0.5% withdrawal fee. This process is costly for depositors and drains the Senior Pool of USDC to utilize.
Being an ERC20 token representing an interest-bearing stablecoin deposit, FIDU has the potential to become interoperable with the rest of DeFi similar to Compound’s cTokens.
The first step towards realizing this would be to create a liquid secondary market between FIDU and USDC on an AMM like Curve. This would allow (a) Goldfinch Liquidity Providers to move in and out of their Senior Pool positions freely without limitations or withdrawal fees, (b) result in less drainage of USDC from the Senior Pool, and (c) allow people to get exposure to the Goldfinch Senior Pool by simply purchasing FIDU on Curve.
Right now, anyone could create a FIDU-USDC Curve pool. However, no one has yet because they would be forgoing juicy GFI token rewards from single-side staking FIDU. This proposal outlines how users could stake FIDU-USDC Curve LP positions to receive their fair share of GFI liquidity mining rewards, which benefits both Senior Pool LPs and the protocol.
Specifications & Requirements
Key Requirements
- On the Goldfinch app, users can stake FIDU-USDC Curve LP tokens for GFI liquidity mining rewards
- Augment the
StakingRewards
contract to accept FIDU-USDC Curve LP tokens - Use the virtual price of the Curve LP position to calculate the appropriate GFI reward amounts
- GFI rewards will come from the existing distribution rate parameters for Senior Pool Liquidity Mining
- GFI rewards from staking FIDU-USDC Curve LP tokens will be subject to the existing unlock schedule
- Implementation should be generalizable so new types of staked positions may be easily added in the future
Specifications
StakingRewards Contract
We’ll augment the StakingRewards contract to accept FIDU-USDC Curve LP tokens and calculate rewards based on the user’s Curve LP position. Broadly, the changes might look something like this (updates highlighted in parentheses):
contract StakingRewards {
// @notice Enum to represent the different staked positions (NEW)
enum StakedPositionType {
Fidu,
CurveLP
}
struct StakedPosition {
// @notice Type of the staked position (NEW)
StakedPositionType positionType,
// @notice Staked amount denominated in `stakingToken().decimals()` (UPDATED)
uint256 amount,
// @notice Exchange rate applied to staked amount to denominate in `baseStakingToken()` (NEW)
uint256 effectiveExchangeRate;
// ...
}
// @notice The address of the base staking token
function baseStakingToken() public view returns (IERC20withDec) {
return config.getFidu();
}
// @notice The address of the token staked for a given position type (new)
function stakingToken(StakedPositionType positionType) internal view returns (IERC20withDec) {
// ...
}
// @param amount The amount of `stakingToken()` to stake
// @param positionType The type of the staking position (new)
// @param lockupPeriod The period over which to lock staked tokens
function stakeWithLockup(
uint256 amount,
StakedPositionType positionType,
LockupPeriod lockupPeriod
) {
uint256 lockDuration = lockupPeriodToDuration(lockupPeriod);
uint256 leverageMultiplier = getLeverageMultiplier(lockupPeriod);
uint256 lockedUntil = block.timestamp.add(lockDuration);
uint256 effectiveExchangeRate = getEffectiveExchangeRate(positionType); // (NEW)
_stakeWithLockup(
msg.sender,
msg.sender,
amount,
effectiveExchangeRate, // (NEW)
lockedUntil,
leverageMultiplier
);
}
// @notice Helper function that calculates the effective exchange rate used to denominate in
// `baseStakingToken()` for any staked position type (NEW)
// @param positionType Type of the staked position
function getEffectiveExchangeRate(StakedPositionType positionType) internal returns (uint256) {
if (type == StakedPositionType.CurveLP) {
return getEffectiveExchangeRateCurveLP()
} else if (type == StakedPositionType.Fidu) {
return 1;
} else {
revert("unsupported StakedPositionType");
}
}
}
The modifications in the StakingRewards
contracts should make it easy to include other new types of staked positions in the future. The current StakingReward
contract only supports staking FIDU directly, so the contract simply calculates individual rewards based on the amount of FIDU staked. To support staking the Curve LP token (and any other future token), we will perform an additional calculation at the time of staking to get the exchange rate that will be used to convert the Curve LP tokens to an effective FIDU amount. The exchange rate for a Curve LP position will be calculated using the virtual price of the LP token given by Curve.
Note: Our proposal uses Curve’s virtual price to calculate the effective FIDU amount instead of spot prices or live ratios of the FIDU-USDC Curve pool to prevent flash loan attacks. You can read more details about how Curve has been exploited here.
Senior Pool Liquidity Mining program
GFI rewards will come from the existing Senior Pool Liquidity Mining program allocation. GFI rewards awarded to Curve LP token staking will be subject to the same unlock schedule as well. As mentioned before, the StakingRewards
implementation will be done such that Curve LP stakers are awarded GFI tokens only for the FIDU portion of the Curve LP position. The USDC portion of their Curve LP position will not earn GFI rewards, preventing “doubling up” of rewards.
Curve pool specifications
Pool name: Goldfinch FIDU/USDC
Pool symbol: fidu-usdc
Type: Non-pegged assets
Token 1 address (FIDU): 0x6a445E9F40e0b97c92d0b8a3366cEF1d67F700BF
Token 2 address (USDC): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Use Curve’s default parameter settings for non-volatile assets:
Amplification (A): 200000000
Gamma: 0.0001
Mid Fee: 0.05
Out Fee: 0.45
Allowed Extra Profit: 0.00000001
Fee Gamma: 0.005
Adjustment Step: 0.0000055
Admin Fee: 50
MA Half Time: 600
Initial Price: 1.04781838714912204*
*The Initial Price will be updated to the current sharePrice
value from the Goldfinch Senior Pool contract (EIP173Proxy | 0x8481a6EbAf5c7DABc3F7e09e44A89531fd31F822) at time of pool creation.
Rationale
We propose using Curve v2 instead of Uniswap or Sushiswap because the AMM design is better suited for non-volatile asset pairs, through the Amplification Parameter A, which is the case for FIDU-USDC.
We propose using USDC as the stablecoin in the pair because it is the stablecoin used for initial Senior Pool deposits.
We propose using the existing distribution rate parameters for Senior Pool Liquidity Mining and the existing GFI rewards unlock schedule to avoid introducing any major changes to the GFI tokenomics.
Development costs
The core development Warbler Labs team is working hard on the roadmap and has limited bandwidth for this project. We propose that we award a one-time development grant of 3,500 GFI from the Community Treasury for the successful completion of this project. If this proposal passes, the proposal authors will be responsible for research, design, and development, and submitting code for public review and security audits.
3,500 GFI = ~$84/hr contractor rate assuming 2 people working for 80 hours, using 60d trailing GFI price of $3.85.
Benefits
- Goldfinch rewards those who increase composability and utility of the FIDU token
- Goldfinch Senior Pool Liquidity Providers can more easily move in and out of their Senior Pool positions without being subject to limitations or withdrawal fees
- Less drainage of USDC from the Goldfinch Senior Pool which keeps TVL high
- Allows people to get exposure to the Goldfinch Senior Pool simply by purchasing FIDU on Curve
- Provides these benefits without changing liquidity mining distribution parameters or unlock schedules
Downsides
- Potentially lower withdrawal fees for the protocol as people could swap on Curve instead of withdrawing
Voting
YES vote: Approve a change to allow staking of FIDU-USDC Curve LP tokens on Goldfinch, and include the FIDU portion of the position in the Senior Pool Liquidity Mining program. These GFI rewards will be subject to the same existing distribution rate parameters and token unlock schedule. This change would be funded with a 3,500 GFI development grant from the Community Treasury.
NO vote: Reject the proposed changes. Do not approve a change to allow the staking of FIDU-USDC Curve LP tokens on Goldfinch to participate in the Senior Pool Liquidity Mining program.
Resources
Goldfinch Senior Pool Liquidity Mining program
Introduction to Curve documentation
Curve v2 factory pool creation parameters
Example contributor grant proposal from Compound
- 500 COMP per year at $479 per COMP (Jul '21) = ~$239,500 per year
- This grant proposal passed with on-chain voting here