Grim Finance Vault V2 - Audit Report
Audit Summary
Grim Finance is building a vault in which users deposit a designated LP token and earn rewards from a yield farming strategy.
For this audit, we reviewed the GrimVaultV2 contract at commit 2377d90a3191a866f339d660d038e6343246f15b on the team's private Github repository.
Please ensure trust in the team prior to investing as they have some control in the ecosystem.
Date: December 31st, 2021.
Audit Findings
GrimVaultV2.sol - Finding #1 - Informational
Description: The following functions are declared public, but are never called internally:Recommendation: These functions can be declared external for additional gas savings on each call.GrimVault.getPricePerFullShare() - Line #960 GrimVault.proposeStrat() - Line #1036 GrimVault.upgradeStrat() - Line #1052
Contract Overview
- Anyone can use this contract to deposit any amount of the designated LP token into the underlying Strategy contract and receive an amount of shares in return based on the amount of LP tokens the user is depositing in relation to the amount of LP tokens that are currently in the system.
- Users can withdraw from the Vault at any time, exchanging their shares for a proportional amount of LP tokens in return. In the event that there are not enough LP tokens to cover the withdrawal, the contract will transfer its balance of LP tokens and consider the shares withdrawn.
- In the case that some amount of the designated LP tokens get stuck in the contract, anyone is able to trigger the earn() function to deposit them into the Strategy contract.
- The owner is able to change the underlying Strategy contract, but must submit a proposal in order to do so and wait until the approval delay time has elapsed before upgrading the Strategy.
- Upon upgrading the Strategy, the LP tokens from the Strategy are withdrawn into the Vault contract and immediately deposited into the new Strategy contract.
- The owner is able to withdraw any tokens, except for the designated LP token, from the contract at any time.
- The Strategy contract was not provided in the scope of this audit, so we are unable to provide an assessment of this contract with regards to security.
- The contract utilizes ReentrancyGuard in the deposit() function, as well as proper structuring of logic within the withdraw() function, to prevent reentrancy attacks.
- As the contract utilizes the SafeMath library, it is protected from any overflow-related attacks.
External Threat Results
Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | N/A | PASS |
Centralization of Control | N/A | PASS |
Delegate Call to Untrusted Contract | N/A | PASS |
Dependence on Predictable Variables | N/A | PASS |
Deprecated Opcodes | N/A | PASS |
Ether Thief | N/A | PASS |
Exceptions | N/A | PASS |
External Calls | N/A | PASS |
Integer Over/Underflow | N/A | PASS |
Multiple Sends | N/A | PASS |
Suicide | N/A | PASS |
State Change External Calls | N/A | PASS |
Unchecked Retval | N/A | PASS |
User Supplied Assertion | N/A | PASS |
Critical Solidity Compiler | N/A | PASS |
Overall Contract Safety | PASS |
Function Graph
Inheritence Chart
Functions Overview
($) = payable function
# = non-constant function
+ Context
- [Int] _msgSender
- [Int] _msgData
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Lib] SafeMath
- [Int] add
- [Int] sub
- [Int] sub
- [Int] mul
- [Int] div
- [Int] div
- [Int] mod
- [Int] mod
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Prv] _functionCallWithValue #
+ ERC20 (Context, IERC20)
- [Pub] #
- [Pub] name
- [Pub] symbol
- [Pub] decimals
- [Pub] totalSupply
- [Pub] balanceOf
- [Pub] transfer #
- [Pub] allowance
- [Pub] approve #
- [Pub] transferFrom #
- [Pub] increaseAllowance #
- [Pub] decreaseAllowance #
- [Int] _transfer #
- [Int] _mint #
- [Int] _burn #
- [Int] _approve #
- [Int] _setupDecimals #
- [Int] _beforeTokenTransfer #
+ [Lib] SafeERC20
- [Int] safeTransfer #
- [Int] safeTransferFrom #
- [Int] safeApprove #
- [Int] safeIncreaseAllowance #
- [Int] safeDecreaseAllowance #
- [Prv] _callOptionalReturn #
+ Ownable (Context)
- [Int] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
+ ReentrancyGuard
+ [Int] IStrategy
- [Ext] vault
- [Ext] want
- [Ext] beforeDeposit #
- [Ext] deposit #
- [Ext] withdraw #
- [Ext] balanceOf
- [Ext] harvest #
- [Ext] retireStrat #
- [Ext] panic #
- [Ext] pause #
- [Ext] unpause #
- [Ext] paused
+ GrimVault (ERC20, Ownable, ReentrancyGuard)
- [Pub] #
- modifiers: ERC20
- [Pub] want
- [Pub] balance
- [Pub] available
- [Pub] getPricePerFullShare
- [Ext] depositAll #
- [Pub] deposit #
- modifiers: nonReentrant
- [Pub] earn #
- [Ext] withdrawAll #
- [Pub] withdraw #
- [Pub] proposeStrat #
- modifiers: onlyOwner
- [Pub] upgradeStrat #
- modifiers: onlyOwner
- [Ext] inCaseTokensGetStuck #
- modifiers: onlyOwner