Automatic boosting with Alluo
How exactly does this looping process work?
Alluo stakes underlying LP deposits into the Vault and carries out all the looping of rewards:
1. StakeUnderlying()
2. farm() in the Alluo Boosting Pool
/// @notice Claims all rewards, exchange all rewards for LPs and stake them
/// @dev Exchanges all rewards (including those sent by the vault) for the entryToken, adds liquidity for LP tokens and then stakes them
/// This function is not to be called directly, but rather through the vault contract it is linked to.
function farm() onlyRole(DEFAULT_ADMIN_ROLE) external {
// 1. Claim all rewards accumulated by booster pool and convert to the entryToken
claimRewardsFromPool();
for (uint256 i; i < yieldTokens.length(); i++) {
address token = yieldTokens.at(i);
uint256 balance = IERC20MetadataUpgradeable(token).balanceOf(address(this));
if (token != address(entryToken) && balance > 0) {
IERC20MetadataUpgradeable(token).safeIncreaseAllowance(address(exchange), balance);
exchange.exchange(token, address(entryToken), balance, 0);
}
}
uint256 totalPoolEntryTokenYield = entryToken.balanceOf(address(this));
// 2. Get all the rewards from the different vaults and keep track of how much entryToken it is worth for each vault
uint256 totalVaultEntryTokenDeposits;
uint256[] memory entryTokenDeposits = new uint256[](vaults.length());
for (uint256 i; i < vaults.length(); i++) {
address _vault = vaults.at(i);
uint256 vaultEntryTokenBalance = IAlluoVault(_vault).claimAndConvertToPoolEntryToken(address(entryToken));
totalVaultEntryTokenDeposits += vaultEntryTokenBalance;
entryTokenDeposits[i] = vaultEntryTokenBalance;
}
// 3. Convert all entryToken balance (rewards by booster + rewards from vault) into reward tokens and then stake into convex
uint256 entryTokenBalance = entryToken.balanceOf(address(this));
uint256 newRewardTokens;
if (entryTokenBalance > 0) {
entryToken.safeIncreaseAllowance(address(exchange), entryTokenBalance);
newRewardTokens = exchange.exchange(address(entryToken), address(rewardToken), entryTokenBalance, 0);
rewardToken.safeIncreaseAllowance(address(cvxBooster), newRewardTokens);
}
// 4. Now give shares of the pool to the vaults which deposited entryToken by calculating how much of they own of the rewardToken LP amount that was created
// 5. Update all vault holder reward balances
uint256 totalVaultNewRewardTokens = newRewardTokens * totalVaultEntryTokenDeposits / entryTokenBalance;
uint256 totalPoolShareholdersNewRewardTokens = newRewardTokens * totalPoolEntryTokenYield / entryTokenBalance;
uint256 totalSharesBefore = totalBalances;
for (uint256 j; j < vaults.length(); j++) {
address _vault = vaults.at(j);
uint256 shareOfRewardTokens = totalVaultNewRewardTokens * entryTokenDeposits[j] / totalVaultEntryTokenDeposits;
uint256 additionalSharesOfVault = _convertToSharesAfterPoolRewards(shareOfRewardTokens, totalPoolShareholdersNewRewardTokens, totalSharesBefore);
balances[_vault] += additionalSharesOfVault;
totalBalances += additionalSharesOfVault;
// 5. Update all vault holder reward balances
}
cvxBooster.deposit(poolId, newRewardTokens, true);
for (uint256 j; j < vaults.length(); j++) {
address _vault = vaults.at(j);
IAlluoVault(_vault).loopRewards();
}
}Last updated