AutoPoolYieldSource
Inherits: YieldSource, IAutoPoolYieldSource
Yield source for the FEYAutoPoolProduct that generates yield by depositing into TraderJoe AutoPools
This contract inherits GACManaged which extends Pausable also uses the GAC for access control
State Variables
autoPoolVault
Address of the AutoPoolVault
IAutoPoolVault public immutable autoPoolVault;
autoPoolTokenDecimals
AutoPool Token decimals
uint256 private immutable autoPoolTokenDecimals;
APT_FARM
Address of the AutoPool token farm
IAPTFarm internal constant APT_FARM = IAPTFarm(0x57FF9d1a7cf23fD1A9fd9DC07823F950a22a718C);
aptFarmId
FarmId of the AutoPool vault
uint256 public aptFarmId;
numRewards
It will be 1 if there is no rewarder, 2 otherwise
uint256 public numRewards;
rewardToken2
Address of the additional reward token if rewarder exists
IERC20Metadata public rewardToken2;
isReward2Native
Flag that indicates if reward2 is native token
bool public isReward2Native;
lbRouter
Address of the LiquidityBook router contract
ILBRouter internal immutable lbRouter = ILBRouter(0xb4315e873dBcf96Ffd0acd8EA43f689D8c20fB30);
lbQuoter
Address of the LiquidityBook quoter contract
ILBQuoter internal immutable lbQuoter = ILBQuoter(0x64b57F4249aA99a812212cee7DAEFEDC40B203cD);
joeToken
Address of the JOE Token contract
IERC20Metadata internal immutable joeToken = IERC20Metadata(0x6e84a6216eA6dACC71eE8E6b0a5B7322EEbC0fDd);
tokenA
Address of the tokenA of the Pool.
IERC20Metadata public immutable tokenA;
tokenB
Address of the tokenB of the Pool.
IERC20Metadata public immutable tokenB;
tokenADecimals
ERC20 tokenA decimals.
uint8 private immutable tokenADecimals;
tokenBDecimals
ERC20 tokenB decimals.
uint8 private immutable tokenBDecimals;
totalShares
the total shares owned by all products that use this contract
uint256 public totalShares;
totalAutoPoolShareTokens
the total share tokens owned by all products that use this contract
uint256 public totalAutoPoolShareTokens;
productAPTShare
mapping to track the product shares allocation
mapping(address => uint256) public productAPTShare;
nextRoundIndexToBeProcessed
Index to track the last processed item in the roundIds array for redemption
uint256 public nextRoundIndexToBeProcessed;
maxIterations
Max no.of iterations during redemption to prevent accidentally exceeding the block gas limit
uint256 public maxIterations = 5;
slippage
Slippage tolerance for recompoundRewards()
uint256 public slippage = Constants.DEFAULT_SLIPPAGE;
roundIds
Tracks roundIds in which the products are queued for withdrawal
uint256[] public roundIds;
roundInfo
Redemption Details for each round
mapping(uint256 => DataTypes.Round) public roundInfo;
WAVAX
address payable internal constant WAVAX = payable(0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7);
structPriceOracle
IStructPriceOracle public immutable structPriceOracle;
nativeToTokenASwapPath
address[] public nativeToTokenASwapPath;
nativeToTokenBSwapPath
address[] public nativeToTokenBSwapPath;
joeToNativeSwapPath
address[] public joeToNativeSwapPath;
reward2ToNativeSwapPath
address[] public reward2ToNativeSwapPath;
tokenAToTokenBSwapPath
address[] public tokenAToTokenBSwapPath;
tokenBToTokenASwapPath
address[] public tokenBToTokenASwapPath;
Functions
constructor
Initializes the yield source
constructor(IAutoPoolVault _autoPoolVault, IGAC _globalAccessControl, IStructPriceOracle _structPriceOracle);
Parameters
Name | Type | Description |
---|---|---|
_autoPoolVault | IAutoPoolVault | The address of the AutoPoolVault |
_globalAccessControl | IGAC | The GAC contract |
_structPriceOracle | IStructPriceOracle |
supplyTokens
Supplies liquidity to the LP.
Construct swap path array
Only PRODUCT contracts can call this method
function supplyTokens(uint256 _amountAIn, uint256 _amountBIn)
external
payable
gacPausable
nonReentrant
onlyRole(PRODUCT)
returns (uint256 _investedTokenA, uint256 _investedTokenB);
Parameters
Name | Type | Description |
---|---|---|
_amountAIn | uint256 | |
_amountBIn | uint256 |
Returns
Name | Type | Description |
---|---|---|
_investedTokenA | uint256 | The amount of tokenA actually supplied to LP (in WAD) |
_investedTokenB | uint256 |
recompoundRewards
Pull tokens from the product contract Update autoPoolShareTokensTotal
Used to harvest and reinvest rewards to accure compounded yields
Only KEEPER account can call this method
function recompoundRewards() public gacPausable onlyRole(KEEPER);
queueForRedemption
Queue for redemption in the AutoPool.
Only PRODUCT contracts can call this method
function queueForRedemption() external gacPausable nonReentrant onlyRole(PRODUCT);
queueForRedemptionSansRecompound
Queue for redemption in the AutoPool without recompounding rewards
Only PRODUCT contracts can call this method
function queueForRedemptionSansRecompound() external gacPausable nonReentrant onlyRole(PRODUCT);
redeemTokens
Used to execute queued withdrawals for the latest round from AutoPool
Only KEEPERS can call this method
function redeemTokens() external gacPausable nonReentrant onlyRole(KEEPER);
sharesToTokens
Fetch the latest round Id We only allow 10 processRedemption (maxIteration) to be called for each redeemToken() call. We will only redeem tokens for a specific round if we can run processRedemption for all products in that round.
See documentation at {YieldSource}
function sharesToTokens(uint256 _shares, uint256 _currentTotalShares, uint256 _currentTotalExternalShares)
external
pure
returns (uint256);
setMaxIterations
Used to updated the maxIterations
value
Can only be called by accounts with GOVERNANCE
role
function setMaxIterations(uint256 _maxIterations) external onlyRole(GOVERNANCE);
setSwapPath
Used to update the swap path
function setSwapPath(DataTypes.SwapPathType _swapPath, address[] memory _newPath) external onlyRole(GOVERNANCE);
Parameters
Name | Type | Description |
---|---|---|
_swapPath | DataTypes.SwapPathType | The swap path to be updated |
_newPath | address[] | The new swap path |
harvestRewards
Allows GOVERNANCE to manually harvest rewards from the farm
function harvestRewards() external onlyRole(GOVERNANCE);
rescueTokens
Used to rescue tokens that are either stuck or accidentally sent to this contract
function rescueTokens(IERC20Metadata _tokenAddress, uint256 _amount, address _recipient, bool _isNative)
external
onlyRole(GOVERNANCE);
Parameters
Name | Type | Description |
---|---|---|
_tokenAddress | IERC20Metadata | Address of the ERC20 token |
_amount | uint256 | Amount of the token to be transferred in token decimals |
_recipient | address | The address of the receiver |
_isNative | bool | Flag to indicate if the native token should be rescued. |
updateFarmInfo
Used to update farm details in case a farm is created for the pool after deployment
function updateFarmInfo() external onlyRole(GOVERNANCE);
setSlippage
Used to update slippage
function setSlippage(uint256 _newSlippage) external onlyRole(GOVERNANCE);
emergencyWithdrawFromFarm
Used to emergency withdraw AP tokens from the AP farm
function emergencyWithdrawFromFarm() public onlyRole(GOVERNANCE);
emergencyWithdrawFromAutoPool
Used to emergency withdraw underlying from the AP vault
Will fail if emergency mode has not been set on the AP vault
function emergencyWithdrawFromAutoPool() public onlyRole(GOVERNANCE);
emergencyWithdrawAndRescue
Used to emergency withdraw from the AP farm, withdraw underlying from the AP vault, and rescue tokens
Will fail if emergency mode has not been set on the vault
function emergencyWithdrawAndRescue(address _recipient) external onlyRole(GOVERNANCE);
Parameters
Name | Type | Description |
---|---|---|
_recipient | address | The address of the receiver |
emergencyRedeemQueuedWithdrawal
Used to emergency redeem queued withdrawals from AutoPool
function emergencyRedeemQueuedWithdrawal(uint256 _roundId) external onlyRole(GOVERNANCE);
Parameters
Name | Type | Description |
---|---|---|
_roundId | uint256 | RoundId to indicate from which round we need to withdraw funds |
_queueForRedemption
Queues a given product for redemption
function _queueForRedemption() internal;
_depositAPTToFarm
Derive product details for the current round for redemption.
If no.of products for present round is equal to max iterations, revert
We record round info to iterate through in redeemTokens()
Update state variables.
Deposits the APT tokens into the farming pool
function _depositAPTToFarm(uint256 _aptAmount) internal;
Parameters
Name | Type | Description |
---|---|---|
_aptAmount | uint256 | Amount of APT tokens to be supplied to the farm |
_recompoundRewards
function _recompoundRewards() internal;
_harvestRewards
Harvests the rewards accumulated in the farming pool and recompound it by converting it into LP tokens
function _harvestRewards() internal returns (uint256 reward1, uint256 reward2);
Returns
Name | Type | Description |
---|---|---|
reward1 | uint256 | The amount of rewardTokens1 received from the farm |
reward2 | uint256 | The amount of rewardTokens2 received from the farm |
_increaseAllowanceAndSwap
reward2 exists only if it is a dual reward farm harvest the rewards factor-in reward2
Used to set allowance and perform a swap based on the given params
function _increaseAllowanceAndSwap(uint256 _amount, IERC20Metadata _token, address[] memory _path) internal;
Parameters
Name | Type | Description |
---|---|---|
_amount | uint256 | The total amount to be swapped |
_token | IERC20Metadata | The address of the token to be swapped |
_path | address[] | The path for the swap |
_recompoundRewards
Used to swap tokens and add liquidity for recompounding rewards
function _recompoundRewards(uint256 _reward1Harvested, uint256 _reward2Harvested, uint256 _wavaxBalanceBefore)
internal
virtual;
Parameters
Name | Type | Description |
---|---|---|
_reward1Harvested | uint256 | Amount of reward1 received from harvesting rewards |
_reward2Harvested | uint256 | Amount of reward2 received from harvesting rewards |
_wavaxBalanceBefore | uint256 | Balance of WAVAX in the contract before harvesting rewards |
_getTokenRate
If reward1 tokens are neither tokenA and tokenB, swap all reward1 tokens to the native token
Set _hasNativeReward to true as we are going to swap all reward1 tokens to WAVAX
If reward2 is there, it would be either WAVAX, AVAX or other token
if WAVAX, then do nothing, just set _hasNativeReward
to true, so that we can swap equally to tokenA and tokenB
If AVAX. wrap it to WAVAX then do the same above.
If other token, swap reward 2 accrued to wavax
If there are native tokens, check if they are srTokens or jrTokens
If they are srTokens, swap half to jrTokens
If they are jrTokens, swap half to srTokens
Else swap it to equal amounts of srTokens and jrTokens
Validates and returns the exchange rate for the given assets from the chainlink oracle and AMM.
This is required to prevent oracle manipulation attacks.
function _getTokenRate(address[] memory _path, uint256 _amount) internal view returns (bool, uint256);
Parameters
Name | Type | Description |
---|---|---|
_path | address[] | The path to get the exchange rate from the AMM (TraderJoe Liquidity Book) |
_amount | uint256 | The amount of tokens to be swapped |
_rescueTokens
Calculate the exchange rate using the prices from StructPriceOracle (Chainlink price feed) Calculate the exchange rate using the Router Check if the relative price diff % is within the MAX_DEVIATION if yes, return the exchange rate and true flag if not, return the rate as 0 and false flag
function _rescueTokens(IERC20Metadata _tokenAddress, uint256 _amount, address _recipient, bool _isNative) internal;
_updateFarmInfo
function _updateFarmInfo(address _autoPoolVault) internal;
getRoundInfo
Returns the roundInfo
for the given round id
function getRoundInfo(uint256 _roundId) external view returns (DataTypes.Round memory _roundInfo);