Factor Vault Strategies

Smart Contract Audit Report

Audit Summary

Factor Vault Strategies Audit Report Factor is creating new strategies which use various methods and platforms in order to generate rewards for users. These strategies are intended to be used in conjunction with their Vaults.

For this audit, we reviewed Factor's select contracts at commit 7396b325abfba46522b9fa5e7d9038f422763503 on the team's private GitHub repository.

Audit Findings

All findings have been resolved, though some centralized aspects are present.
Date: July 5th, 2023.
Updated: July 12th, 2023 to reflect changes from commit e6db260c7bd89b83691cfdbcb9a7cf236d7616c3 to commit f1891d74426bcfd3b3d674b929c2020e38599c0e.
Updated: July 19th, 2023 to reflect changes from commit f1891d74426bcfd3b3d674b929c2020e38599c0e to commit 00405f1d56f0f1a8b0c4d55df2ba3cae97944502.
Updated: July 21st, 2023 to include the PendleStrategy contract at commit 7f24c2c0a5ef2437390aacaccba6a902b7309f32.
Updated: July 25th, 2023 to reflect changes from commit 00405f1d56f0f1a8b0c4d55df2ba3cae97944502 to commit ac8955f3701b9f5b881da56eb1b68025c6663d30.
Updated: July 27th, 2023 to include additional Strategy contracts.
Updated: August 3rd, 2023 to include additional Strategy contracts and reflect changes from commit ac8955f3701b9f5b881da56eb1b68025c6663d30 to commit 1cf102a673b99d8975fca4ef777a3b545cc2ad3c.
Updated: August 7th, 2023 to reflect changes from commit 1cf102a673b99d8975fca4ef777a3b545cc2ad3c to commit 7396b325abfba46522b9fa5e7d9038f422763503.

Finding #1 - LodeStarStrategy, MuxStrategy, PlutusStrategy, RadiantStrategy, SiloStrategy, SiloStrategyMulti, TraderJoeStrategy, TenderStrategy, PendlerETHStrategy, PenpieRETHStrategy, PenpieWSTETHStrategy, & PendleStrategy - Medium (Resolved)

Description: All swaps made using these contracts do not specify a minimum amount of tokens to receive.
Risk/Impact: Unlimited slippage can allow frontrunning opportunities in which the contract would receive less funds than they should when rewards are swapped if either the reward amount is large enough or the harvester fee is small enough.
Recommendation: The project team should use a TWAP in order to determine minimum expected amounts to receive. The team can also consider monitoring frontrunning and either harvest more frequently or adjust the harvester fee to incentivize more frequent harvesting if abuse is detected.
Update: The MuxStrategy and RadiantStrategy contracts now use an external Price Oracle in order to calculate a minimum amount of tokens to receive, and the TraderJoeStrategy contract now uses Chainlink to calculate a minimum amount of tokens to receive. The LodeStarStrategy, PlutusStrategy, SiloStrategy, and SiloStrategyMulti contracts now use a getAmountsOut() function in order to calculate minimum amounts to receive, which is still susceptible to price manipulation.
Resolution: The team intends to harvest small reward amounts frequently, enable harvest on deposit functionality, and monitor the Strategies for any potential frontrunning abuse.

Finding #2 - GLPStrategy & PlutusStrategy - Medium (Resolved)

Description: These contracts do not specify a minimum amount of GLP to receive when minting GLP through the GMXRouter contract.
Risk/Impact: Unlimited slippage can allow frontrunning opportunities where the contract receives less GLP from a WETH deposit than intended if deposited WETH rewards are large enough.
Recommendation: The project team should use a TWAP in order to determine minimum expected GLP amounts to receive. The team can also consider monitoring frontrunning and harvest more frequently if abuse is detected.
Resolution: The team intends to harvest small reward amounts frequently, enable harvest on deposit functionality, and monitor these Strategies for any potential frontrunning abuse.

Finding #3 - GLPStrategy, LodeStarStrategy, MuxStrategy, PlutusStrategy, RadiantStrategy, SiloStrategy, SiloStrategyMulti, & TraderJoeStrategy - Medium (Resolved)

Description: These Strategy contracts are intended to be upgradeable, but inherit the ReentrancyGuard contract.
Risk/Impact: If a contract is upgraded to an implementation using additional storage slots, functionality could break or not work as intended.
Recommendation: The ReentrancyGuardUpgradeable contract should be inherited instead, which includes empty storage space to permit the addition of new variables without breaking functionality.
Resolution: The team has implemented the above recommendation.

Finding #4 - RadiantStrategy - Medium (Resolved)

Description: The changeRouter function's "balancerSwapActive" parameter shares the same name as a state variable. When attempting to set the state variable in this function, the local variable will be referenced instead.
function changeRouter(bool balancerSwapActive) external onlyManager {
	balancerSwapActive = balancerSwapActive;
}
Risk/Impact: The changeRouter() function will not update the contract's balancer flag when called.
Recommendation: The project team should rename the balancerSwapActive parameter.
Resolution: The team has implemented the above recommendation.

Finding #5 - StratManager - Medium (Resolved)

Description: The setSlippage() function incorrectly updates the call fee instead of the slippage.
Risk/Impact: The owner will not be able to update the slippage, and may unintentionally set the call fee to an incorrect amount upon attempting to update the permitted slippage percent.
Recommendation: The setSlippage() function should update the slippage variable instead of the callFee variable.
Resolution: The team has implemented the above recommendation.

Finding #6 - PenpieRETHStrategy - Low (Resolved)

Description: Rewards are not immediately deposited into the PenpieDepositorHelper upon harvesting.
Risk/Impact: As the withdraw() function only withdraws funds from the PenpieDepositorHelper, withdrawals from the Strategy may fail even if the combined asset balance of the Strategy and the PenpieDepositorHelper is sufficient for the withdrawal amount.
Recommendation: Harvested rewards should be immediately deposited into the PenpieDepositorHelper contract.
Resolution: The team has implemented the above recommendation.

Finding #7 - GLPStrategy - Informational (Resolved)

Description: The GLPStrategy’s withdraw() function withdraws the contract’s entire Vault asset balance instead of the specified amount, despite the following line:
require(amount <= totalBalance, "Insufficient total balance");
Recommendation: The project team should either remove the mentioned require statement or update the contract's logic to reflect intended functionality.
Resolution: The withdraw() function now withdraws only the specified asset amount from the contract.

Finding #8 - GLPStrategy - Informational (Resolved)

Description: The GLPStrategy’s withdraw() function transfers its entire asset balance, then uses its resulting asset balance for the "Withdrawal" event. A value of 0 will always be emitted as a result.
Recommendation: The Withdrawal event should reflect the token amount withdrawn.
Resolution: The team has implemented the above recommendation.

Finding #9 - MuxStrategy - Informational (Resolved)

Description: The MuxStrategy's StrategyHarvested event will emit the amount charged in fees instead of the amount harvested due to the following lines in the _harvest() function:
uint256 prevBalance = IERC20(usdc).balanceOf(address(this));
chargeFees(callFeeRecipient);
uint256 afterBalance = IERC20(usdc).balanceOf(address(this));
uint256 harvested = prevBalance - afterBalance;
emit StrategyHarvested(msg.sender, harvested);
Recommendation: The StrategyHarvested event should instead reflect the number of tokens harvested.
Resolution: The team has implemented the above recommendation.

Finding #10 - PlutusStrategy & PendleStrategy - Informational (Resolved)

Description: The PlutusStrategy and PendleStrategy's harvestOnDeposit flags cannot be updated. As a result, harvest on deposit functionality cannot be enabled in these contracts.
Recommendation: The project team should add a setHarvestOnDeposit() function to allow the team to update this flag.
Resolution: The team has implemented the above recommendation.

Contracts Overview

  • These Strategy contracts are intended to be deposited into and withdrawn from by their associated Vaults.
  • A Strategy's owner can update its Manager address at any time.
  • A Strategy's owner or Manager can update its Keeper address at any time.
  • A Strategy's owner can update its Router address or Factor Fee Recipient address at any time.
  • A Strategy's "Strategist" address can update its address at any time.
  • A Strategy's owner or Manager can update its performance fee, withdrawal fee, deposit fee, Factor fee, Strategist fee, Call fee, and slippage percentage at any time.
  • A Strategy's Vault can upgrade the contract at any time.
  • All swaps are made using associated Router contracts.
  • As the Router and Vault contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
  • The contracts utilize ReentrancyGuard to prevent against reentrancy attacks in applicable functions.
  • As the contracts are implemented with Solidity v0.8.0, they are safe from any possible overflows/underflows.
GLPStrategy Contract:
  • This Strategy deposits funds into the GMX platform in order to earn rewards.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • Any user can trigger a harvest at any time, which claims WETH rewards earned by the GMXRouter contract and deposits them into the GMXRouter in exchange for additional GLP after a performance fee is taken.
  • This fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • When the Vault asset is withdrawn from the Strategy, a withdrawal fee is taken and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all GLP is redeemed for WETH and transferred to the associated Vault contract.
  • The owner or Manager can enter panic mode at any time. When panic mode is enabled, the contract is paused and all GLP is redeemed for WETH and stored in this contract.
  • A Strategy contract's owner or Manager can pause the contract at any time, disabling harvesting and the deposited() function.
  • The Owner or Manager can toggle the harvest on deposit flag at any time.
  • As the GMXRouter and GLPManager contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
LodeStarStrategy Contract:
  • This Strategy uses deposited funds to earn rewards through the LodeStar platform.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • The owner or Keeper can harvest at any time, which first claims any LodeToken rewards from the LodeTroller contract.
  • These tokens are swapped for LodeStar deposit tokens using the contract's associated Camelot router address and deposited into the LodeComp contract using its mint() function after a performance fee is taken.
  • This fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • When the Vault asset is withdrawn from the Strategy, a withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all funds are redeemed for LodeStar deposit tokens from the LodeComp contract and transferred to the associated Vault contract.
  • The owner or Manager can enter panic mode at any time. When panic mode is enabled, the contract is paused and deposited funds are withdrawn from the LodeComp contract and stored in this contract. The LodeTroller contract's exitMarket() function is then called.
  • A Strategy contract's owner or Manager can pause the contract at any time, disabling harvesting and depositing functionality.
  • The Owner or Manager can toggle the harvest on deposit flag at any time.
  • As the LodeTroller, LodeComp, and LodeReward contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
MuxStrategy Contract:
  • This Strategy uses deposited funds to earn rewards through MUX protocol.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • The resulting deposited funds are staked into the associated RewardRouter contract.
  • The owner or Keeper can harvest at any time, which first claims any rewards from the RewardRouter contract in the form of the blockchain's native token and swaps them for USDC.
  • A performance fee is taken and divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • The remaining USDC is deposited into the associated OrderBook contract using its placeLiquidityOrder() function. This contract's resulting Mux token balance is then staked into the associated RewardRouter contract in exchange for Vault asset tokens.
  • When the Vault asset is withdrawn from the Strategy, funds are first unstaked from the RewardRouter contract if needed. A withdrawal fee is then taken and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, the all funds are unstaked from the RewardRouter and transferred to the associated Vault contract.
  • A Strategy contract's owner or Manager can pause the contract at any time, disabling harvesting and the deposited() function.
  • The owner or Manager can enter panic mode at any time, pausing the contract.
  • The owner can update the "uniswaprDepositPool" address at any time, which is not used within this contract.
  • The Owner or Manager can toggle the harvest on deposit flag at any time.
  • As the OrderBook, LodeComp, and LodeReward contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
PlutusStrategy Contract:
  • This Strategy uses deposited PlvGlp to earn rewards through Plutus.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • The owner or Keeper can harvest at any time, which first claims Pls Token rewards from the associated PlutusFarm contract.
  • A performance fee is taken and divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • The contract's remaining Pls Token balance is then swapped for WETH and staked into the GMXRouter contract in exchange for sGLP. This resulting sGLP is deposited into the associated PlutusDepositor contract in exchange for PlvGlp.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • When the PlvGlp is withdrawn from the Strategy, a withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, the contract's current PlvGlp balance is transferred to the associated Vault contract.
  • A Strategy contract's owner or Manager can pause the contract at any time, disabling harvesting and depositing functionality.
  • The owner or Manager can enter panic mode at any time, pausing the contract.
  • As the PlutusDepositor, Pls Token, sPls Token, and PlutusFarm contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
RadiantStrategy Contract:
  • This Strategy uses deposited funds to farm rewards through the Radiant Capital platform.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • Any user can trigger a harvest at any time, which claims Radiant token rewards from the RadiantIncentive contract.
  • If the "balancer swap" flag is enabled, harvested rewards are swapped for WETH using the associated BalancerVault contract. Otherwise the swap is executed using the associated Router contract.
  • An additional swap is subsequently made using the contract's resulting WETH balance in exchange for the Radiant deposit asset.
  • After a performance fee is taken, the deposit asset is deposited into the RadiantLendingPool contract.
  • The performance fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • When the Vault asset is withdrawn from the Strategy, a withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all Vault assets are withdrawn from the RadiantLendingPool contract and transferred to the associated Vault.
  • A Strategy contract's owner or Manager can pause the contract at any time, disabling harvesting and depositing functionality.
  • The owner or Manager can enter panic mode at any time. This pauses the contract and withdraws all deposited funds from the RadiantLendingPool into this contract.
  • The Owner or Manager can update the pools used for non-balancer swaps at any time.
  • The Owner or Manager can toggle both the balancer swap and harvest on deposit flags at any time.
  • As the RadiantIncentive, BalancerVault, and RadiantLendingPool contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
SiloStrategy Contract:
  • This Strategy uses deposited funds to farm rewards through the Silo platform.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • The owner or Keeper can harvest at any time, which claims Silo token rewards from the SiloIncentiveController and swaps them for the Silo deposit asset.
  • After a performance fee is taken, the resulting assets are deposited into the SiloStrategy contract.
  • The performance fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • When the Vault asset is withdrawn from the Strategy, a withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all Vault assets are withdrawn from the SiloStrategy contract and transferred to the associated Vault.
  • When panic mode is enabled, funds are withdrawn from the SiloStrategy contract and stored in this contract.
  • A Strategy contract's owner or Manager can pause the contract at any time, disabling harvesting and depositing functionality.
  • The Owner or Manager can toggle the harvest on deposit flag at any time.
  • As the SiloIncentiveController and SiloStrategy contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
SiloStrategyMulti Contract:
  • This Strategy uses deposited funds to farm rewards from multiple SiloStrategy contracts.
  • When funds are deposited into this contract, they are subsequently deposited into the specified SiloStrategy address.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • The owner or Keeper can harvest at any time, which claims Silo token rewards from the SiloIncentiveController and swaps them for the Silo deposit asset.
  • After a performance fee is taken, the resulting assets are divided and deposited into various SiloStrategy contracts based on this contract's allocation ratio for each SiloStrategy.
  • The performance fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • When the Vault asset is withdrawn from the Strategy, funds are withdrawn proportionally from each SiloStrategy based on their allocation ratio and subsequently transferred to the Vault.
  • If the Vault "exits" this Strategy, all Vault assets are withdrawn from all SiloStrategy contracts and transferred to the associated Vault.
  • The owner or Manager can enter panic mode at any time. When panic mode is enabled, the contract is paused and funds are withdrawn from all SiloStrategy contracts and stored in this contract.
  • A Strategy contract's owner or Manager can pause the contract at any time, disabling harvesting and depositing functionality.
  • The Owner or Manager can toggle the harvest on deposit flag at any time.
  • The Owner or Manager execute a "rebalance" at any time, which withdraws all the assets from the associated Strategies and redeposits them according to the updated specified allocation ratios.
  • As the SiloIncentiveController and SiloStrategy, and contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
  • The project team should ensure that deposits are distributed proportionally to each pool according to each pool's allocation ratio.
TraderJoeStrategy Contract:
  • This Strategy uses deposited funds to farm rewards through the TraderJoe platform.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • Any address can trigger this contract to deposit any of its Vault assets into the associated StableJoeStaking contract.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every user deposit if the contract's beforeDeposit() function is called.
  • Any address can harvest at any time, which claims USDC rewards from the associated StableJoeStaking contract.
  • A performance fee is taken from the harvested rewards and divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • The remaining USDC after fees is swapped for the Vault asset along a path determined by the associated LBQuoter contract. The resulting funds are then deposited into the StableJoeStaking contract.
  • When the Vault asset is withdrawn from the Strategy, the specified amount is withdrawn from the LodeComp contract and subsequently transferred to the Vault after a withdrawal fee is taken.
  • If the Vault "exits" this Strategy, all Vault assets are withdrawn from the StableJoeStaking contract and transferred to the associated Vault.
  • The owner or Manager can enter panic mode at any time. When panic mode is enabled, the contract is paused and all funds are withdrawn from the StableJoeStaking contract and stored in this contract.
  • A Strategy contract's owner or Manager can pause the contract at any time, disabling harvesting and depositing functionality.
  • The Owner or Manager can toggle the harvest on deposit flag at any time.
  • As the StableJoeStaking, LBQuoter, and LodeComp contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
PendleStrategy Contract:
  • This Strategy uses deposited Pendle Market tokens to earn rewards through the Pendle platform.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • The owner or Keeper address can harvest PendleToken rewards from the PendleMarket address at any time.
  • After a performance fee is taken, any resulting PendleTokens in the contract are swapped for WETH; WETH is then swapped for WSTETH using the contract's associated BalancerVault contract.
  • This WSTETH is swapped for pTokens and added as liquidity in exchange for additional PendleMarket tokens using the PendleRouter contract. These assets are stored in this contract.
  • The performance fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • When the Vault asset is withdrawn from the Strategy, a withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all funds are transferred to the associated Vault contract.
  • Harvesting and the deposited() function are disabled while the contract is paused.
  • Entering panic mode automatically pauses this contract.
  • The owner or Manager can toggle the harvest on deposit flag at any time.
  • As the PendleToken, PendleMarket, PendleRouter, and BalancerVault contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
PendlerETHStrategy Contract:
  • This Strategy uses deposited Pendle Market tokens to earn rewards through the Pendle platform.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • The owner or Keeper address can harvest PendleToken rewards from the PendleMarket address at any time.
  • After a performance fee is taken, any resulting PendleTokens in the contract are swapped for WETH; WETH is then swapped for RETH using the contract's associated BalancerVault contract.
  • This RETH is swapped for pTokens and added as liquidity in exchange for additional PendleMarket tokens using the PendleRouter contract.
  • The performance fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • When the Vault asset is withdrawn from the Strategy, a withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all funds are transferred to the associated Vault contract.
  • Harvesting and the deposited function are disabled while the contract is paused.
  • Entering panic mode automatically pauses this contract.
  • As the PendleToken, PendleMarket, BalancerVault, and mentioned token contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
PerennialStrategy Contract:
  • This contract holds tokens deposited into the associated Vault contract.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • When the Vault asset is withdrawn from the Strategy, a withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all funds are transferred to the associated Vault contract.
  • Depositing functionality is disabled while the contract is paused.
  • Entering panic mode automatically pauses this contract.
RedactedStrategy Contract:
  • This contract holds tokens deposited into the associated Vault contract.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • When the Vault asset is withdrawn from the Strategy, a withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all funds are transferred to the associated Vault contract.
  • Depositing functionality is disabled while the contract is paused.
  • Entering panic mode automatically pauses this contract.
OliveStrategy Contract:
  • This contract uses deposited GLP to earn rewards through the OliveVault contract.
  • Deposited GLP is immediately deposited into the associated OliveVault contract if the deposited() function is called; no deposit fee is taken.
  • When the Vault asset is withdrawn from the Strategy, they are first withdrawn from the OliveVault.
  • A withdrawal fee is then taken and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all funds are withdrawn from the OliveVault and transferred to the associated Vault contract.
  • Depositing functionality is disabled while the contract is paused.
  • Entering panic mode automatically pauses this contract.
  • As the OliveVault and GLP contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to its security or functionality.
TenderStrategy Contract:
  • This Strategy uses deposited funds to farm rewards through the Tender platform.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • The owner or Keeper can harvest at any time, which claims Tender token rewards from the TenderTroller contract.
  • Once claimed, the resulting tokens are used to instantly vest "Tender Vested Tokens" through the TenderInstantVester contract.
  • These tokens are then swapped for the TenderComp's deposit asset. If the deposit asset is ETH, an additional exchange from WETH to ETH is made.
  • A performance fee is taken from the resulting amount; the remainder is used to mint additional Vault asset tokens using the TenderComp contract.
  • The performance fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • When the Vault asset is withdrawn from the Strategy, a withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all Vault assets are withdrawn from the TenderComp contract and transferred to the associated Vault.
  • The owner or Manager can pause the contract at any time, disabling harvesting and depositing functionality.
  • When panic mode is enabled, the contract is paused and all deposited funds are withdrawn from the TenderComp contract and stored in this contract.
  • The owner or Manager can toggle the harvest on deposit flag at any time.
  • As the TenderComp, TenderTroller, TenderInstantVester, and mentioned token contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
VelaStrategy Contract:
  • This Strategy uses deposited funds to farm rewards through the Vela platform.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • The remaining deposit amount is deposited into the VelaTokenFarm contract.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • Any address can harvest at any time, which claims esVela token rewards from the VelaTokenFarm contract.
  • The resulting esVela is deposited back into the VelaTokenFarm contract, and vested Vela tokens are subsequently withdrawn from the same VelaTokenFarm contract.
  • VelaTokens are then swapped to WETH and then to USDC, where an associated Price Oracle contract along with the contract's specified slippage amount is used to calculate the minimum resulting amounts to receive.
  • A performance fee is taken from the contract's resulting USDC; the remainder is staked into the VelaVault contract.
  • The performance fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • When the Vault asset is withdrawn from the Strategy, they are withdrwan from the VelaTokenFarm. A withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all Vault assets are unstaked from the VelaVault and VelaTokenFarm contracts and transferred to the associated Vault.
  • The owner or Manager can pause the contract at any time, disabling harvesting and depositing functionality.
  • When panic mode is enabled, the contract is paused and all deposited funds are withdrawn from the VelaVault and VelaTokenFarm contracts and stored in this contract.
  • The owner or Manager can toggle the harvest on deposit flag at any time.
  • As the VelaTokenFarm, Price Oracle, and mentioned token contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
PenpieRETHStrategy Contract:
  • This Strategy uses deposited Pendle Market tokens to earn rewards through the Penpie and Pendle platforms.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • The remaining funds in the contract are immediately deposited into the PenpieDepositorHelper contract.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • The owner or Keeper address can harvest both Penpie token and Pendle token rewards from the MasterPenpie address at any time.
  • Rewards of each token are swapped for WETH, and a performance fee is taken.
  • The resulting WETH is then swapped for RETH using the contract's associated BalancerVault contract, then swapped for pTokens and added as liquidity in exchange for additional PendleMarket tokens using the PendleRouter contract.
  • The performance fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • When the Vault asset is withdrawn from the Strategy, they are first withdrawn from the Penpie platform through the PenpieDepositorHelper contract. A withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all funds are withdrawn through the PenpieDepositorHelper and transferred to the associated Vault contract.
  • Harvesting and the deposited function are disabled while the contract is paused.
  • Entering panic mode automatically pauses this contract.
  • The owner or Manager can toggle the harvest on deposit flag at any time.
  • As the PenpieDepositorHelper, MasterPenpie, PendleMarket, BalancerVault, and mentioned token contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.
PenpieWSTETHStrategy Contract:
  • This Strategy uses deposited Pendle Market tokens to earn rewards through the Penpie and Pendle platforms.
  • A deposit fee is taken from a user's deposit and transferred to the Factor Fee Recipient address if the appropriate deposit functions are called by the associated Vault.
  • The remaining funds in the contract are immediately deposited into the PenpieDepositorHelper contract.
  • If the "harvest on deposit" flag is enabled, harvests are automatically triggered on every deposit if the contract's beforeDeposit() function is called.
  • The owner or Keeper address can harvest both Penpie token and Pendle token rewards from the MasterPenpie address at any time.
  • Rewards of each token are swapped for WETH, and a performance fee is taken.
  • The resulting WETH is then swapped for WSTETH using the contract's associated BalancerVault contract, then swapped for pTokens and added as liquidity in exchange for additional PendleMarket tokens using the PendleRouter contract.
  • These PendleMarket tokens are immediately deposited into the Penpie platform through the PenpieDepositorHelper contract.
  • The performance fee is divided between the harvester, Factor Fee Recipient address, and Strategist address based on the call fee, factor fee, and strategist fee percentages, respectively.
  • When the Vault asset is withdrawn from the Strategy, they are first withdrawn from the Penpie platform through the PenpieDepositorHelper contract. A withdrawal fee is taken from the withdrawal amount and transferred to the Factor Fee Recipient address; the remainder is transferred to the Vault.
  • If the Vault "exits" this Strategy, all funds are withdrawn through the PenpieDepositorHelper and transferred to the associated Vault contract.
  • Harvesting and the deposited function are disabled while the contract is paused.
  • Entering panic mode automatically pauses this contract.
  • The owner or Manager can toggle the harvest on deposit flag at any time.
  • As the PenpieDepositorHelper, MasterPenpie, PendleMarket, BalancerVault, and mentioned token contracts were not included within the scope of this audit, we are unable to provide an assessment with regards to their security or functionality.

Audit Results

Vulnerability Category Notes Result
Arbitrary Jump/Storage Write N/A PASS
Centralization of Control
  • The owner and Manager Role have the permissions described above.
  • The owner or Manager can pause a Strategy at any time.
  • The owner or Manager can update fees to up to 100% at any time.
  • All Strategies can be updated by their associated Vault contracts at any time.
  • WARNING
    Compiler Issues N/A PASS
    Delegate Call to Untrusted Contract N/A PASS
    Dependence on Predictable Variables N/A PASS
    Ether/Token Theft N/A PASS
    Flash Loans N/A PASS
    Front Running
  • Large swaps could be susceptible to frontrunning as described in Findings #1 and #2.
  • PASS
    Improper Events N/A PASS
    Improper Authorization Scheme N/A PASS
    Integer Over/Underflow N/A PASS
    Logical Issues N/A PASS
    Oracle Issues N/A PASS
    Outdated Compiler Version N/A PASS
    Race Conditions N/A PASS
    Reentrancy N/A PASS
    Signature Issues N/A PASS
    Sybil Attack N/A PASS
    Unbounded Loops N/A PASS
    Unused Code N/A PASS
    Overall Contract Safety   PASS

    Contract Source Summary and Visualizations

    Name

    Address/Source Code

    Visualized
    (Hover-Zoom Recommended)

    StratManager

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    EmptyStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    EmptyStrategyMulti

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    GLPStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    LodeStarStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    MuxStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    PlutusStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    RadiantStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    TraderJoeStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    SiloStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    SiloStrategyMulti

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    PendleStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    PendlerETHStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    PerennialStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    RedactedStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    OliveStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    TenderStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    VelaStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    PenpieRETHStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    PenpieWSTETHStrategy

    GitHub (Not yet deployed on mainnet)

    Inheritance Chart.  Function Graph.

    About SourceHat

    SourceHat has quickly grown to have one of the most experienced and well-equipped smart contract auditing teams in the industry. Our team has conducted 1800+ solidity smart contract audits covering all major project types and protocols, securing a total of over $50 billion U.S. dollars in on-chain value!
    Our firm is well-reputed in the community and is trusted as a top smart contract auditing company for the review of solidity code, no matter how complex. Our team of experienced solidity smart contract auditors performs audits for tokens, NFTs, crowdsales, marketplaces, gambling games, financial protocols, and more!

    Contact us today to get a free quote for a smart contract audit of your project!

    What is a SourceHat Audit?

    Typically, a smart contract audit is a comprehensive review process designed to discover logical errors, security vulnerabilities, and optimization opportunities within code. A SourceHat Audit takes this a step further by verifying economic logic to ensure the stability of smart contracts and highlighting privileged functionality to create a report that is easy to understand for developers and community members alike.

    How Do I Interpret the Findings?

    Each of our Findings will be labeled with a Severity level. We always recommend the team resolve High, Medium, and Low severity findings prior to deploying the code to the mainnet. Here is a breakdown on what each Severity level means for the project:

    • High severity indicates that the issue puts a large number of users' funds at risk and has a high probability of exploitation, or the smart contract contains serious logical issues which can prevent the code from operating as intended.
    • Medium severity issues are those which place at least some users' funds at risk and has a medium to high probability of exploitation.
    • Low severity issues have a relatively minor risk association; these issues have a low probability of occurring or may have a minimal impact.
    • Informational issues pose no immediate risk, but inform the project team of opportunities for gas optimizations and following smart contract security best practices.