Skip to content
$1,000,000 in security audit grants are live now, Apply here →

Security review · March 2022

StrategyGeistEth

for Beefy Finance

After a line by line manual analysis and automated review, Guardian Audits has concluded that:

Published
Language
Solidity
Chains
Fantom
Sector
Yield and vaults
  • 0 Critical
  • 0 High
  • 0 Medium
  • 8 Low
  • 0 Informational

8 resolved

Scope

Overview

After a line by line manual analysis and automated review, Guardian Audits has concluded that:

  • Beefy Finance’s smart contracts have a LOW RISK SEVERITY
  • Beefy Finance’s smart contracts have an ACTIVE OWNERSHIP
  • Important owner privileges – panic, pause, deleverageOnce, rebalance, addRewardToNativeRoute, removeRewardToNativeRoute
  • Beefy Finance’s smart contract owner has multiple “write” privileges. Centralization risk correlated to the active ownership is LOW

Findings 8

  1. STR-1 Low Centralization Risk Centralization / Privilege Resolved
    Location
    Global

    Description

    There are several avenues through which the contract’s owner address can remove funds from the strategy contract to another arbitrary address.

    The owner can call the setVault function with an arbitrary and possibly malicious contract address, setting the strategy’s vault to that arbitrary contract. This new arbitrary contract is now free to execute retireStrat and extract the strategy’s funds.

    Additionally, the owner can call the setUnirouter function with an arbitrary and possibly malicious contract address, setting the strategy’s unirouter to that arbitrary contract. The owner can then approve the maximum allowance for any token to that arbitrary address by calling addRewardToNativeRoute, potentially leading to an extraction of the strategy’s funds.

    Recommendation

    Add a contract level timelock for the setUnirouter and setVault functions.

    To mitigate any centralization risk, it is always recommended that controlling addresses be multi-sig and timelocked. It is known that Beefy Finance’s owner address is in fact a timelocked multi-sig, therefore this centralization risk is considered low.

  2. STR-2 Low Unchecked Return Value Control Flow Resolved
    Location
    StrategyGeist.sol

    Description

    Both the transfer and swapExactTokensForTokens functions have return values that should be checked, otherwise some unexpected exception may occur. It is important to have some logic in the event these executions fail.

    Recommendation

    Check the return values, or opt for a safeTransfer alternative.

  3. STR-3 Low Unnecessary Code Code Cleanliness Resolved
    Location
    StrategyGeist.sol

    Description

    The strategy contains 8 individual IERC20(want).balanceOf(address(this)) calls, but this code is already abstracted in the balanceOfWant function.

    Recommendation

    Reuse the balanceOfWant function in these 8 spots for improved code readability and maintainability.

  4. STR-4 Low Function Visibility Modifiers Optimization Resolved
    Location
    StrategyGeist.sol

    Description

    The functions callReward, panic, userAccountData, outputToNative, rewardToNative, and nativeToWant are marked as public, but are never called from inside the contract.

    Recommendation

    The functions callReward, panic, userAccountData, outputToNative, rewardToNative, and nativeToWant can be marked external for gas optimization.

  5. STR-5 Low Contract Inheritance Structure Code Cleanliness Resolved
    Location
    StrategyGeist.sol

    Description

    The StrategyGeist contract inherits from the StratManager and FeeManager contracts, but notice that the FeeManager contract also inherits from the StratManager contract.

    Recommendation

    Alter the inheritance hierarchy so that there are no redundancies, or provide a veritable reason for such an inheritance structure.

  6. STR-6 Low Redundant Require Statement Code Cleanliness Resolved
    Location
    StrategyGeist.sol

    Description

    The require(msg.sender == vault, "!vault") require statement appears 3 separate times at the beginning of beforeDeposit, withdraw, and retireStrat.

    Recommendation

    Consider making this requires statement into a reusable modifier.

  7. STR-7 Low Incongruent Error Strings Code Cleanliness Resolved
    Location
    StrategyGeist.sol

    Description

    The contract contains two require statements: require(_borrowRate <= borrowRateMax, "!safe") on line 1596 and require(_borrowRate <= borrowRateMax, "!rate") on line 1616 that enforce the same restrictions, but yield different error strings.

    Recommendation

    Consider standardizing these error strings.

  8. STR-8 Low Extraneous Function Code Cleanliness Resolved
    Location
    StrategyGeist.sol

    Description

    The implementation for the harvest and managerHarvest functions is exactly the same, the only difference being that the manager can call the managerHarvest function.

    Recommendation

    Remove the managerHarvest function or provide a veritable reason for its existence.

Put your code through the same review.

This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.

Get a quote