Introduction
From July 17th to August 7th, 2023, Shellboxes partnered with Velvet Capital to undertake a comprehensive security assessment of the Velvet Capital V2. Our meticulous evaluation centered on identifying potential security vulnerabilities linked to the deployment of smart contracts. By highlighting potential semantic inconsistencies between the smart contract code and its design document, we aimed to offer a clear perspective on areas of improvement. Furthermore, we proposed innovative solutions to refine the existing codebase. Preliminary findings suggest that the current iteration of the smart contracts, while robust, presents several security and performance challenges that warrant attention and refinement.
About Velvet Capital
Velvet Capital stands as a pioneering DeFi protocol, designed to empower both individuals and institutions in the creation of tokenized index funds, portfolios, and a range of other financial products, all while offering enhanced yield opportunities. At its core, the protocol furnishes a comprehensive infrastructure tailored for the development of financial products. By seamlessly integrating with Automated Market Makers (AMMs), Lending protocols, and a myriad of other DeFi primitives, Velvet Capital offers its users a versatile and expansive asset management toolkit.
Our Partnership
Velvet Capital entrusted ShellBoxes with the responsibility of evaluating the security of their DeFi protocol. By employing a systematic approach, we delved deep to pinpoint potential security vulnerabilities tied to the implementation of their smart contracts. Additionally, we provided constructive feedback and recommendations to enhance the existing codebase. Our in-depth analysis revealed that the current iteration of smart contracts, while robust, still harbors multiple security and performance challenges that can be effectively addressed.
Auditing Approach
The ShellBoxes team, when assessing Velvet Capital, grappled with the intricate task of harmonizing key elements such as speed, efficiency, precision, and the overall scope of the audit. To adeptly navigate this multifaceted challenge, a blend of both manual and automated testing methodologies was employed. Manual testing was indispensable for unearthing errors in logic, procedural flows, and execution sequences. It played a pivotal role in validating the protocol’s invariants, ensuring they were congruent with the business logic and accurately mirrored in the code. Such rigorous examination was essential to guarantee the early detection and mitigation of potential security vulnerabilities.
On the flip side, automated testing was harnessed to expand the audit’s breadth and swiftly pinpoint any code segments that deviated from recognized security standards. This approach allowed the ShellBoxes team to encompass a vast audit landscape and rapidly identify potential security lapses. By integrating these methodologies, the team achieved a harmonious blend of speed, pragmatism, accuracy, and comprehensiveness, ensuring a thorough and exhaustive security evaluation of Velvet Capital.
Findings
Throughout the audit process, the Velvet Capital team showcased exemplary professionalism and dedication. Their proactive approach, combined with thorough documentation, significantly streamlined the audit. It was evident that they prioritized security, as they swiftly addressed and rectified the majority of the identified vulnerabilities. While the smart contracts of Velvet Capital are fundamentally well-architected and crafted, there remains room for enhancement in their implementation. The audit revealed a spectrum of vulnerabilities, categorized as follows:
- Critical-severity: 2 vulnerabilities
- High-severity: 6 vulnerabilities
- Medium-severity: 8 vulnerabilities
- Low-severity: 7 vulnerabilities
- Informational-severity: 2 vulnerabilities
We will delve deeper into each severity category to provide a detailed overview of the identified vulnerabilities.
Critical Findings
During the audit of Velvet Capital’s smart contracts, several critical vulnerabilities were identified:
- Potential Over-Minting of Tokens: In the swapOffChainTokens function, users could input arbitrary buy amounts, potentially leading to token over-minting. An attacker could exploit this by depositing unbalanced allocations, receiving more index tokens than their actual deposit. The team rectified this by using a custom aggregator for fair LP price calculation.
- StreamingFee Check Denial of Service: The calculateStreamingFee function could revert if called multiple times within the same block, leading to a potential denial of service. The team resolved this by returning zero when the last charge is equal to the current block timestamp.
These vulnerabilities, while critical, were promptly addressed by the Velvet Capital team, showcasing their commitment to security and the safety of their users.
High Findings
During the audit of Velvet Capital’s smart contracts, the following high-severity vulnerabilities were identified:
- Incorrect Token Price Calculation: The contract used a hardcoded value of 1e18 to represent one token when fetching prices from Chainlink, leading to incorrect price calculations for tokens with different decimals. This could result in a denial of service for main functionalities. The team addressed this by dynamically calculating token representation based on token decimals.
- Inaccuracy in LP Token Price Calculation: A mismatch in decimal representation in the _calculatePrice function led to inaccuracies in LP token price calculations. The team mitigated this by using a custom aggregator for fair LP price calculation.
- Flaw in Share Minting: The _swapTokenToToken function failed to update the swapResult array when both input and output tokens were primary tokens. This oversight could lead to users receiving fewer index tokens than they should. The team addressed this flaw by assigning the return value from _swapTokenToETH to the swapResult.
- Misevaluation of User’s Investments in LP Tokens: The investInFund function inaccurately evaluated the value of a user’s investment in liquidity provider (LP) tokens, potentially due to the phenomenon known as impermanent loss. This could misrepresent a user’s portfolio value, posing financial risks. The team rectified this by using a custom aggregator for fair LP price calculation.
- Potential Portfolio Imbalance Due to OffChain Swaps: The protocol’s allowance for significant discrepancies between user-inputted values and calculated values for off-chain exchanges could lead to portfolio imbalances. This imbalance could trigger multiple rebalancing transactions, incurring additional fees and potential financial losses. The team mitigated this by adjusting the amount validation process.
- Bypass of Withdrawal Cooldown Period Restriction: The investInFund function allowed users to bypass withdrawal restrictions by transferring index tokens to another address. This could enable users to withdraw funds before the end of the cooldown period. The team addressed this vulnerability by adding a check in the _beforeTokenTransfer function, ensuring the cooldown period is respected before allowing token transfers.
These high-severity vulnerabilities, while concerning, were promptly addressed by the Velvet Capital team, further emphasizing their dedication to ensuring the security and safety of their users.
Medium Findings
During the audit of Velvet Capital’s smart contracts, the following medium-severity vulnerabilities were identified:
- Flaw in Share Minting: A delay in Chainlink price feeds could be exploited, allowing users to withdraw and re-deposit funds after a value increase, effectively obtaining more index tokens without changing their balance. This could lead to unauthorized fund withdrawals. The team mitigated the risk, by removing the USD to BNB conversion in the minting calculation.
- Unfair Distribution of Rewards: The claimTokens function could lead to an unfair distribution of rewards if not invoked before any investInFund call. A new depositor might receive rewards generated by other investors. The team plans to specify the harvest time and frequency in the strategy, allowing users to choose their investment time accordingly.
- Griefing Attack in Withdrawal Process: An attacker could exploit the withdrawal function to grief any investor by updating their lastInvestmentTime, preventing them from withdrawing funds. The team addressed this by removing the option for users to invest on behalf of someone else and adapting the cooldown period.
- Hard-coded Slippage Leading to Potential Fund Freeze: The contract’s hardcoded slippage of 10% could lead to fund freezes in volatile market conditions. The team plans to adapt the maxSlippage in volatile market conditions.
- Potential Sandwich Attack Due to Chainlink Oracle Failure: The AMM handlers’ reliance on Chainlink without proper checks could expose users to sandwich attacks if Chainlink fails. The team addressed this by reverting the transaction when the price feed returns zero.
- Lack of Freshness Check for Chainlink Price Feed Data: The contract did not check the updatedAt value from Chainlink’s latestRoundData function, potentially using stale data. The team addressed this by requiring the updatedAt to not be older than an oracleExpirationThreshold.
- Precision Loss in Price Calculation: The getPriceTokenUSD18Decimals function had a precision loss issue due to the order of operations. The team resolved this by changing the operation order to perform multiplications before divisions.
- Mismatch Between _tokenAmount and buyAmounts Array: The investInFundOffChain function could lead to uninvested funds due to a mismatch between _tokenAmount and the buyAmounts array. The team addressed this by returning the unused funds to the investor.
These medium-severity vulnerabilities, while concerning, were promptly addressed by the Velvet Capital team, further emphasizing their dedication to ensuring the security and safety of their users.
Low Findings
During the audit of Velvet Capital’s smart contracts, the following low-severity vulnerabilities were identified:
- Unchecked Transfer Return Value: The contract’s _safeTokenTransfer function did not verify the return value of a token transfer. This could lead to unnoticed failed transfers. The team addressed this by adding a check for the transfer function’s return status.
- Missing Array Length Check: The _addFeed function did not ensure that the lengths of input arrays were equal, leading to potential transaction reverts or skipped elements. The team added a check to ensure array lengths are consistent.
- Missing Maximum Amount for User Supplied Slippage: The getSlippage function did not have a maximum slippage value, which could lead to unfavorable swaps. The team added a safety maxSlippage to ensure user-supplied slippage is reasonable.
- Potential Out of Gas Exception: The initToken and updateTokenList functions did not limit the length of the _tokens array, risking an Out of Gas exception. The team introduced a limitation to the array’s size.
- Potential Failure of Off-Chain Investment: The swapOffChainTokens function could revert if any token in the _tokens array was not enabled. The team removed the whitelist check from this function.
- Potential Unrestricted Withdrawals During Pause State: The triggerMultipleTokenWithdrawal function allowed withdrawals even when the protocol was paused. The team removed the notPaused modifier from the withdrawOffChain function for consistent behavior.
- Precision Loss When Dividing Odd Integers: The contract could lose precision when dividing odd integers by two due to Solidity’s floor division. The team adjusted the division approach to address this precision loss.
These low-severity findings highlight areas where the contract could be improved for better precision, security, and functionality. The team has taken steps to address each of these concerns, enhancing the overall robustness of the contract.
Informational Findings
During the audit of Velvet Capital’s smart contracts, the following informational-severity vulnerabilities were identified:
- Lack of Cross-Contract Reentrancy Protection: The triggerMultipleTokenWithdrawal function in the contract lacks protection against potential cross-contract reentrancy attacks. The team implemented a cross-contract reentrancy guard using the CommonReentrancyGuard contract.
- Off-Chain Investment Failure Due to Non-Zero Protocol Fees: The investInFundOffChain function in the OffChainIndexSwap contract can fail if a user passes any non-zero protocol fee value. The team removed the unused protocolFee parameter, addressing the potential issue.
Best Practices
Several best practices were highlighted to enhance the contract’s efficiency and clarity. These encompass removing redundant initializations, omitting unnecessary self-approvals, phasing out the use of SafeMath libraries post Solidity version 0.8.0, eliminating unused Ether calls in the IndexSwap function, refining loops for efficiency in the _swapTokenToTokens function, and pruning unused variables and events. Implementing these recommendations can bolster the contract’s robustness, streamline its operations, and mitigate potential vulnerabilities in the future.
Conclusion
In the comprehensive audit of Velvet Capital V2’s contracts, a spectrum of issues, ranging from critical to minor, were identified. Out of these, 22 were promptly addressed and rectified by the Velvet Capital team, demonstrating their commitment to security and functionality. While some issues were deemed to have a low likelihood of occurrence, they remain on record as potential areas of concern. Shellboxes’ auditors commend the proactive approach of the Velvet Capital team and emphasize the importance of continued vigilance. It’s crucial for Velvet Capital to remain cognizant of these findings, ensuring that future iterations and operations remain free from vulnerabilities and complications.