Skip to main content

StakingRewards

StakingRewards

Deployment on Ethereum mainnet:

https://etherscan.io/address/0xFD6FF39DA508d281C2d255e9bBBfAb34B6be60c3

LockupPeriod

enum LockupPeriod {
SixMonths,
TwelveMonths,
TwentyFourMonths
}

StakedPositionType

enum StakedPositionType {
Fidu,
CurveLP
}

StakedPosition

struct StakedPosition {
uint256 amount;
struct StakingRewardsVesting.Rewards rewards;
uint256 leverageMultiplier;
uint256 lockedUntil;
enum StakingRewards.StakedPositionType positionType;
uint256 unsafeEffectiveMultiplier;
uint256 unsafeBaseTokenExchangeRate;
}

RewardsParametersUpdated

event RewardsParametersUpdated(address who, uint256 targetCapacity, uint256 minRate, uint256 maxRate, uint256 minRateAtPercent, uint256 maxRateAtPercent)

TargetCapacityUpdated

event TargetCapacityUpdated(address who, uint256 targetCapacity)

VestingScheduleUpdated

event VestingScheduleUpdated(address who, uint256 vestingLength)

MinRateUpdated

event MinRateUpdated(address who, uint256 minRate)

MaxRateUpdated

event MaxRateUpdated(address who, uint256 maxRate)

MinRateAtPercentUpdated

event MinRateAtPercentUpdated(address who, uint256 minRateAtPercent)

MaxRateAtPercentUpdated

event MaxRateAtPercentUpdated(address who, uint256 maxRateAtPercent)

EffectiveMultiplierUpdated

event EffectiveMultiplierUpdated(address who, enum StakingRewards.StakedPositionType positionType, uint256 multiplier)

MULTIPLIER_DECIMALS

uint256 MULTIPLIER_DECIMALS

OWNER_ROLE

bytes32 OWNER_ROLE

ZAPPER_ROLE

bytes32 ZAPPER_ROLE

config

contract GoldfinchConfig config

lastUpdateTime

uint256 lastUpdateTime

The block timestamp when rewards were last checkpointed

accumulatedRewardsPerToken

uint256 accumulatedRewardsPerToken

Accumulated rewards per token at the last checkpoint

rewardsAvailable

uint256 rewardsAvailable

Total rewards available for disbursement at the last checkpoint, denominated in `rewardsToken()`

positionToAccumulatedRewardsPerToken

mapping(uint256 => uint256) positionToAccumulatedRewardsPerToken

StakedPosition tokenId => accumulatedRewardsPerToken at the position's last checkpoint

targetCapacity

uint256 targetCapacity

Desired supply of staked tokens. The reward rate adjusts in a range around this value to incentivize staking or unstaking to maintain it.

minRate

uint256 minRate

The minimum total disbursed rewards per second, denominated in `rewardsToken()`

maxRate

uint256 maxRate

The maximum total disbursed rewards per second, denominated in `rewardsToken()`

maxRateAtPercent

uint256 maxRateAtPercent

The percent of `targetCapacity` at which the reward rate reaches `maxRate`. Represented with `MULTIPLIER_DECIMALS`.

minRateAtPercent

uint256 minRateAtPercent

The percent of `targetCapacity` at which the reward rate reaches `minRate`. Represented with `MULTIPLIER_DECIMALS`.

vestingLength

uint256 vestingLength

The duration in seconds over which legacy rewards vest. New positions have no vesting and earn rewards immediately.

UNUSED (definition kept for storage slot)

totalStakedSupply

uint256 totalStakedSupply

Supply of staked tokens, denominated in `stakingToken().decimals()` Note that due to the use of `unsafeBaseTokenExchangeRate` and `unsafeEffectiveMultiplier` on a StakedPosition, the sum of `amount` across all staked positions will not necessarily equal this `totalStakedSupply` value; the purpose of the base token exchange rate and the effective multiplier is to enable calculation of an "effective amount" -- which is what this `totalStakedSupply` represents the sum of.

totalLeveragedStakedSupply

uint256 totalLeveragedStakedSupply

UNUSED (definition kept for storage slot)

leverageMultipliers

mapping(enum StakingRewards.LockupPeriod => uint256) leverageMultipliers

UNUSED (definition kept for storage slot)

positions

mapping(uint256 => struct StakingRewards.StakedPosition) positions

NFT tokenId => staked position

effectiveMultipliers

mapping(enum StakingRewards.StakedPositionType => uint256) effectiveMultipliers

A mapping of staked position types to multipliers used to denominate positions in `baseStakingToken()`. Represented with `MULTIPLIER_DECIMALS`.

initialize

function __initialize__(address owner, contract GoldfinchConfig _config) external

initZapperRole

function initZapperRole() external

stakedBalanceOf

function stakedBalanceOf(uint256 tokenId) external view returns (uint256)

Returns the staked balance of a given position token.

The value returned is the bare amount, not the effective amount. The bare amount represents the number of tokens the user has staked for a given position.

NameTypeDescription
tokenIduint256A staking position token ID
NameTypeDescription
[0]uint256Amount of staked tokens denominated in `stakingToken().decimals()`

rewardsToken

function rewardsToken() internal view returns (contract IERC20withDec)

The address of the token being disbursed as rewards

stakingToken

function stakingToken(enum StakingRewards.StakedPositionType positionType) internal view returns (contract IERC20)

The address of the token that is staked for a given position type

baseStakingToken

function baseStakingToken() internal view returns (contract IERC20withDec)

The address of the base token used to denominate staking rewards

_additionalRewardsPerTokenSinceLastUpdate

function _additionalRewardsPerTokenSinceLastUpdate(uint256 time) internal view returns (uint256)

The additional rewards earned per token, between the provided time and the last time rewards were checkpointed, given the prevailing `rewardRate()`. This amount is limited by the amount of rewards that are available for distribution; if there aren't enough rewards in the balance of this contract, then we shouldn't be giving them out.

NameTypeDescription
[0]uint256Amount of rewards denominated in `rewardsToken().decimals()`.

rewardPerToken

function rewardPerToken() public view returns (uint256)

Returns accumulated rewards per token up to the current block timestamp

NameTypeDescription
[0]uint256Amount of rewards denominated in `rewardsToken().decimals()`

earnedSinceLastCheckpoint

function earnedSinceLastCheckpoint(uint256 tokenId) public view returns (uint256)

Returns rewards earned by a given position token from its last checkpoint up to the current block timestamp.

NameTypeDescription
tokenIduint256A staking position token ID
NameTypeDescription
[0]uint256Amount of rewards denominated in `rewardsToken().decimals()`

totalOptimisticClaimable

function totalOptimisticClaimable(address owner) external view returns (uint256)

optimisticClaimable

function optimisticClaimable(uint256 tokenId) public view returns (uint256)

claimableRewards

function claimableRewards(uint256 tokenId) public view returns (uint256 rewards)

Returns the rewards claimable by a given position token at the most recent checkpoint, taking into account vesting schedule for legacy positions.

NameTypeDescription
rewardsuint256Amount of rewards denominated in `rewardsToken()`

totalVestedAt

function totalVestedAt(uint256 start, uint256 end, uint256 time, uint256 grantedAmount) external pure returns (uint256 rewards)

Returns the rewards that will have vested for some position with the given params.

NameTypeDescription
rewardsuint256Amount of rewards denominated in `rewardsToken()`

rewardRate

function rewardRate() internal view returns (uint256)

Number of rewards, in `rewardsToken().decimals()`, to disburse each second

_positionToEffectiveAmount

function _positionToEffectiveAmount(struct StakingRewards.StakedPosition position) internal view returns (uint256)

toEffectiveAmount

function toEffectiveAmount(uint256 amount, uint256 safeBaseTokenExchangeRate, uint256 safeEffectiveMultiplier) internal pure returns (uint256)

Calculates the effective amount given the amount, (safe) base token exchange rate, and (safe) effective multiplier for a position

Do NOT pass in the unsafeBaseTokenExchangeRate or unsafeEffectiveMultiplier in storage. Convert it to safe values using `safeBaseTokenExchangeRate()` and `safeEffectiveMultiplier()`

NameTypeDescription
amountuint256The amount of staked tokens
safeBaseTokenExchangeRateuint256The (safe) base token exchange rate. See @dev comment below.
safeEffectiveMultiplieruint256The (safe) effective multiplier. See @dev comment below.

stakingAndRewardsTokenMantissa

function stakingAndRewardsTokenMantissa() internal view returns (uint256)

We overload the responsibility of this function -- i.e. returning a value that can be used for both the `stakingToken()` mantissa and the `rewardsToken()` mantissa --, rather than have multiple distinct functions for that purpose, in order to reduce contract size. We rely on a unit test to ensure that the tokens' mantissas are indeed equal and therefore that this approach works.

currentEarnRatePerToken

function currentEarnRatePerToken() public view returns (uint256)

The amount of rewards currently being earned per token per second. This amount takes into account how many rewards are actually available for disbursal -- unlike `rewardRate()` which does not. This function is intended for public consumption, to know the rate at which rewards are being earned, and not as an input to the mutative calculations in this contract.

NameTypeDescription
[0]uint256Amount of rewards denominated in `rewardsToken().decimals()`.

positionCurrentEarnRate

function positionCurrentEarnRate(uint256 tokenId) external view returns (uint256)

The amount of rewards currently being earned per second, for a given position. This function is intended for public consumption, to know the rate at which rewards are being earned for a given position, and not as an input to the mutative calculations in this contract.

NameTypeDescription
[0]uint256Amount of rewards denominated in `rewardsToken().decimals()`.

stake

function stake(uint256 amount, enum StakingRewards.StakedPositionType positionType) external returns (uint256)

Stake `stakingToken()` to earn rewards. When you call this function, you'll receive an an NFT representing your staked position. You can present your NFT to `getReward` or `unstake` to claim rewards or unstake your tokens respectively.

This function checkpoints rewards.

NameTypeDescription
amountuint256The amount of `stakingToken()` to stake
positionTypeenum StakingRewards.StakedPositionTypeThe type of the staked position
NameTypeDescription
[0]uint256Id of the NFT representing the staked position

depositAndStake

function depositAndStake(uint256 usdcAmount) public returns (uint256)

Deposit to SeniorPool and stake your shares in the same transaction.

NameTypeDescription
usdcAmountuint256The amount of USDC to deposit into the senior pool. All shares from deposit will be staked.

depositWithPermitAndStake

function depositWithPermitAndStake(uint256 usdcAmount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external returns (uint256)

Identical to `depositAndStake`, except it allows for a signature to be passed that permits this contract to move funds on behalf of the user.

NameTypeDescription
usdcAmountuint256The amount of USDC to deposit
deadlineuint256
vuint8secp256k1 signature component
rbytes32secp256k1 signature component
sbytes32secp256k1 signature component

depositToCurve

function depositToCurve(uint256 fiduAmount, uint256 usdcAmount) external

Deposits FIDU and USDC to Curve on behalf of the user. The Curve LP tokens will be minted directly to the user's address

NameTypeDescription
fiduAmountuint256The amount of FIDU to deposit
usdcAmountuint256The amount of USDC to deposit

depositToCurveAndStake

function depositToCurveAndStake(uint256 fiduAmount, uint256 usdcAmount) external

depositToCurveAndStakeFrom

function depositToCurveAndStakeFrom(address nftRecipient, uint256 fiduAmount, uint256 usdcAmount) public

Deposit to FIDU and USDC into the Curve LP, and stake your Curve LP tokens in the same transaction.

NameTypeDescription
nftRecipientaddress
fiduAmountuint256The amount of FIDU to deposit
usdcAmountuint256The amount of USDC to deposit

_depositToCurve

function _depositToCurve(address depositor, address lpTokensRecipient, uint256 fiduAmount, uint256 usdcAmount) internal returns (uint256)

Deposit to FIDU and USDC into the Curve LP. Returns the amount of Curve LP tokens minted, which is denominated in 1e18.

NameTypeDescription
depositoraddressThe address of the depositor (i.e. the current owner of the FIDU and USDC to deposit)
lpTokensRecipientaddressThe receipient of the resulting LP tokens
fiduAmountuint256The amount of FIDU to deposit
usdcAmountuint256The amount of USDC to deposit

safeEffectiveMultiplier

function safeEffectiveMultiplier(struct StakingRewards.StakedPosition position) internal view returns (uint256)

Returns the effective multiplier for a given position. Defaults to 1 for all staked positions created prior to GIP-1 (before the `unsafeEffectiveMultiplier` field was added).

Always use this method to get the effective multiplier to ensure proper handling of old staked positions.

safeBaseTokenExchangeRate

function safeBaseTokenExchangeRate(struct StakingRewards.StakedPosition position) internal view returns (uint256)

Returns the base token exchange rate for a given position. Defaults to 1 for all staked positions created prior to GIP-1 (before the `unsafeBaseTokenExchangeRate` field was added).

Always use this method to get the base token exchange rate to ensure proper handling of old staked positions.

getEffectiveMultiplierForPositionType

function getEffectiveMultiplierForPositionType(enum StakingRewards.StakedPositionType positionType) public view returns (uint256)

The effective multiplier to use with new staked positions of the provided `positionType`, for denominating them in terms of `baseStakingToken()`. This value is denominated in `MULTIPLIER_DECIMALS`.

getBaseTokenExchangeRate

function getBaseTokenExchangeRate(enum StakingRewards.StakedPositionType positionType) public view virtual returns (uint256)

Calculate the exchange rate that will be used to convert the original staked token amount to the `baseStakingToken()` amount. The exchange rate is denominated in `MULTIPLIER_DECIMALS`.

NameTypeDescription
positionTypeenum StakingRewards.StakedPositionTypeType of the staked postion

_stake

function _stake(address staker, address nftRecipient, uint256 amount, enum StakingRewards.StakedPositionType positionType) internal returns (uint256 tokenId)

unstake

function unstake(uint256 tokenId, uint256 amount) public

Unstake an amount of `stakingToken()` associated with a given position and transfer to msg.sender. Any remaining staked amount will continue to accrue rewards.

This function checkpoints rewards

NameTypeDescription
tokenIduint256A staking position token ID
amountuint256Amount of `stakingToken()` to be unstaked from the position

unstakeMultiple

function unstakeMultiple(uint256[] tokenIds, uint256[] amounts) external

Unstake multiple positions and transfer to msg.sender.

This function checkpoints rewards

NameTypeDescription
tokenIdsuint256[]A list of position token IDs
amountsuint256[]A list of amounts of `stakingToken()` to be unstaked from the position

unstakeAndWithdraw

function unstakeAndWithdraw(uint256 tokenId, uint256 usdcAmount) external

unstakeAndWithdrawMultiple

function unstakeAndWithdrawMultiple(uint256[] tokenIds, uint256[] usdcAmounts) external

unstakeAndWithdrawInFidu

function unstakeAndWithdrawInFidu(uint256 tokenId, uint256 fiduAmount) external

unstakeAndWithdrawMultipleInFidu

function unstakeAndWithdrawMultipleInFidu(uint256[] tokenIds, uint256[] fiduAmounts) external

_unstakeAndWithdraw

function _unstakeAndWithdraw(uint256 tokenId, uint256 usdcAmount) internal returns (uint256 usdcAmountReceived, uint256 fiduUsed)

_unstakeAndWithdrawInFidu

function _unstakeAndWithdrawInFidu(uint256 tokenId, uint256 fiduAmount) internal returns (uint256 usdcReceivedAmount)

_unstake

function _unstake(uint256 tokenId, uint256 amount) internal

Unstake an amount from a single position

This function does NOT checkpoint rewards; the caller of this function is responsible for ensuring that rewards are properly checkpointed before invocation. This function does NOT transfer staked tokens back to the user; the caller of this function is responsible for ensuring that tokens are transferred back to the owner if necessary.

NameTypeDescription
tokenIduint256The token ID
amountuint256The amount of of `stakingToken()` to be unstaked from the position

kick

function kick(uint256 tokenId) external

"Kick" a user's reward multiplier. If they are past their lock-up period, their reward multiplier will be reset to 1x.

This will also checkpoint their rewards up to the current time.

updatePositionEffectiveMultiplier

function updatePositionEffectiveMultiplier(uint256 tokenId) external

Updates a user's effective multiplier to the prevailing multiplier. This function gives users an option to get on a higher multiplier without needing to unstake.

This will also checkpoint their rewards up to the current time.

getReward

function getReward(uint256 tokenId) public

Claim rewards for a given staked position

NameTypeDescription
tokenIduint256A staking position token ID

addToStake

function addToStake(uint256 tokenId, uint256 amount) external

Add `amount` to an existing FIDU position (`tokenId`)

For non-zapper cases, it is not recommended to call this for vesting positions, as any additions will be vested. It is optimal to create a new non-vesting position and earn more rewards there.

NameTypeDescription
tokenIduint256A staking position token ID
amountuint256Amount of `stakingToken()` to be added to tokenId's position

loadRewards

function loadRewards(uint256 rewards) external

Transfer rewards from msg.sender, to be used for reward distribution

setRewardsParameters

function setRewardsParameters(uint256 _targetCapacity, uint256 _minRate, uint256 _maxRate, uint256 _minRateAtPercent, uint256 _maxRateAtPercent) external

setEffectiveMultiplier

function setEffectiveMultiplier(uint256 multiplier, enum StakingRewards.StakedPositionType positionType) external

Set the effective multiplier for a given staked position type. The effective multipler is used to denominate a staked position to `baseStakingToken()`. The multiplier is represented in `MULTIPLIER_DECIMALS`

NameTypeDescription
multiplieruint256the new multiplier, denominated in `MULTIPLIER_DECIMALS`
positionTypeenum StakingRewards.StakedPositionTypethe type of the position

updateReward

modifier updateReward(uint256 tokenId)

_updateReward

function _updateReward(uint256 tokenId) internal

isAdmin

function isAdmin() internal view returns (bool)

onlyAdmin

modifier onlyAdmin()

isZapper

function isZapper() internal view returns (bool)

isGoListed

function isGoListed() internal view returns (bool)

canWithdraw

function canWithdraw(uint256 tokenId) internal view returns (bool)

RewardAdded

event RewardAdded(uint256 reward)

Staked

event Staked(address user, uint256 tokenId, uint256 amount, enum StakingRewards.StakedPositionType positionType, uint256 baseTokenExchangeRate)

DepositedAndStaked

event DepositedAndStaked(address user, uint256 depositedAmount, uint256 tokenId, uint256 amount)

DepositedToCurve

event DepositedToCurve(address user, uint256 fiduAmount, uint256 usdcAmount, uint256 tokensReceived)

DepositedToCurveAndStaked

event DepositedToCurveAndStaked(address user, uint256 fiduAmount, uint256 usdcAmount, uint256 tokenId, uint256 amount)

Unstaked

event Unstaked(address user, uint256 tokenId, uint256 amount, enum StakingRewards.StakedPositionType positionType)

UnstakedMultiple

event UnstakedMultiple(address user, uint256[] tokenIds, uint256[] amounts)

UnstakedAndWithdrew

event UnstakedAndWithdrew(address user, uint256 usdcReceivedAmount, uint256 tokenId, uint256 amount)

UnstakedAndWithdrewMultiple

event UnstakedAndWithdrewMultiple(address user, uint256 usdcReceivedAmount, uint256[] tokenIds, uint256[] amounts)

RewardPaid

event RewardPaid(address user, uint256 tokenId, uint256 reward)

GoldfinchConfigUpdated

event GoldfinchConfigUpdated(address who, address configAddress)