Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | 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 |
Reentrancy | tokenFallback allows for arbitray code execution, though only to an addressed provided by the team and when tokens are sent to the vault. | Warning |
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 |
HedgeTech Vault - Smart Contract Audit Report
Summary
The HedgeTech Vault is a new project where transaction fees are meant to fund a BNB vault where users can redeem their tokens for BNB; effectively acting as insurance for the protocol. The project will be deployed on the Binance Smart Chain.
For this audit, we reviewed the team's code on GitHub at commit 26fefeb503c20a41916270c08b063202c721866b and 3481d154b72d271bceb5459b5d3f8ed441c923d6. Once deployed, we will verify the code and add the mainnet addresses to this report.
Notes on the Token Contract:The VLT token includes a fee charged on transfers of the token. The tax rate is ~3% and it cannot be changed. The tokens from the fee are intended to be sent directly to the team. The team can update the destination for the fees at any time. The total supply of the token is 100,000, sent to the deployer's address upon deployment. The token implements the (not adopted) EIP223 standard for token fallback functions. This allows for arbitrary code execution (which may be dangerous) any time a user sends tokens directly to the Vault address. In this case, the implementation with the Vault is secure. The owner can choose to enable or disable the transfer tax at any time. Utilization of SafeMath to prevent overflows.
Notes on the Vault Contract:The Vault contract is designed to allow users to swap out their VLT tokens for BNB, based on the proportion of the VTL token's circulating supply and the amount of BNB that has been sent to the vault. The team must manually sell the tokens collected from the tax fee and send the proceeds to the vault in order to fund it. Users can take advantage of this feature by sending their tokens to the vault contract; triggering the tokenFallback() function initializing the swap. This will only work using the transfer() function; transferFrom() will not work for this purpose as tokenFallback() is not called. The EIP223 tokenFallback function is properly protected from misuse by requiring that only the VLT token contract can call it. The VLT token address is set during deployment and can never be updated. While reentrancy may be possible in sendBackEth(), .transfer is utilized thereby limiting gas to 2300, which is insufficient for meaningful arbitrary code execution.
Notes on the TokenLocker Contract:This contract allows project teams to lock their treasury tokens for any period of time, determined by the user depositing tokens. The owner/team has no control over tokens locked into the contract.
Gas Optimizations: (Not Critical)Line 104 of the VLT token checks if at least one of three conditions are met; but the prior if would guarentee at least one of these conditions (recipient == vaultContractAddress) is met. Line 104 and lines 109-117 can therefore be safely removed. Line 145 of the VLT token checks if math operations have been performed correctly, but the operations being checked are already using SafeMath. This line can be safely removed to save gas on transfers. Public functions may be declared external to save a small amount of gas on each transaction.
Audit Findings Summary:
- No security issues from outside attackers were identified.
- The team must manually sell the tokens collected from fees and send the BNB collected to provide rewards. Therefore, ensure trust in the team prior to investing.
- Date: February 21st, 2021.
- Update Date: February 23rd, 2021. Review updated code with limitations on ownership functions per audit recommendations.
- Date: March 4th, 2021. Inclusion of analysis on TokenLocker contract.
Token Contract
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ Context
- [Int] _msgSender
- [Int] _msgData
+ Ownable (Context)
- [Int] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
+ [Int] IVLTRecipient
- [Ext] tokenFallback #
+ [Lib] SafeMath
- [Int] add
- [Int] sub
- [Int] sub
- [Int] mul
- [Int] div
- [Int] div
- [Int] mod
- [Int] mod
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Prv] _verifyCallResult
+ VLT (Context, IERC20, Ownable)
- [Pub] #
- [Pub] name
- [Pub] symbol
- [Pub] decimals
- [Pub] totalSupply
- [Pub] balanceOf
- [Pub] allowance
- [Pub] approve #
- [Pub] transferFrom #
- [Pub] increaseAllowance #
- [Pub] decreaseAllowance #
- [Prv] _approve #
- [Pub] transfer #
- [Int] _transfer #
- [Ext] setTaxReceiveAddress #
- modifiers: onlyOwner
- [Ext] setAddressTax #
- modifiers: onlyOwner
- [Ext] setTaxFraction #
- modifiers: onlyOwner
- [Ext] setVaultContractAddress #
- modifiers: onlyOwner
Vault Contract
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ [Lib] SafeMath
- [Int] add
- [Int] sub
- [Int] sub
- [Int] mul
- [Int] div
- [Int] div
- [Int] mod
- [Int] mod
+ [Int] IERC20
- [Ext] totalSupply
- [Ext] balanceOf
- [Ext] transfer #
- [Ext] allowance
- [Ext] approve #
- [Ext] transferFrom #
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Prv] _verifyCallResult
+ [Int] IVLTRecipient
- [Ext] tokenFallback #
+ Vault (IVLTRecipient)
- [Ext] ($)
- [Pub] #
- [Pub] getVaultETHBalance
- [Pub] getVaultVLTBalance
- [Pub] getCirculatingSupply
- [Pub] tokenFallback #
- [Int] sendBackEth #
TokenLocker Contract
($) = payable function
# = non-constant function
Int = Internal
Ext = External
Pub = Public
+ TokenLocker
- [Pub] #
- [Ext] lockTokens #
- [Pub] getLock
- [Ext] getNumLocks
- [Ext] getEmergencyUnlock
- [Ext] unlockTokens #
- [Ext] emergencyUnlock #
- modifiers: onlyOwner
- [Ext] emergencyLock #
- modifiers: onlyOwner
- [Ext] changeOwner #