Download audit report
This document presents the results of a security review conducted by Nethermind Security for Ventuals LST contracts.
Ventuals brings the power of perps to the most innovative private companies in the world, which is a multi-trillion dollar asset class that normal investors have historically been locked out of.
Ventuals is built on Hyperliquid's proven perps orderbook infrastructure, using the HIP-3 standard.
Ventuals created its own HYPE LST (vHYPE) to raise the HIP-3 stake requirement. vHYPE is a fully transferable ERC20 token, and serves as the claim to the original HYPE plus accrued native staking yield.
The security review was performed in two phases: an initial assessment of the Genesis contracts and a subsequent review of the version adapted for HIP-3.
The initial scope covered the Genesis phase contracts, which allowed users to stake HYPE tokens for a one-year lock-up. In exchange, users received vHYPE, a transferable ERC20 token representing their staked position. The protocol featured auto-compounding for all native staking rewards and was designed for future enhancements using a UUPS upgradeable proxy pattern.
The second phase of the review focused on significant updates, headlined by the introduction of the StakingVaultManager contract to replace the GenesisVaultManager. This new contract introduces a batched withdrawal system with a 7-day delay queue. Furthermore, a slashing mechanism was implemented that can affect both actively staked funds and assets in the withdrawal queue. These changes required corresponding modifications to the RoleRegistry, StakingVault, and VHYPE contracts.
The audit comprises 1000 lines of Solidity code. The audit was performed using (a) manual analysis of the codebase, and (b) automated analysis tools.
| Audit assessment | |
| Audit Type | Security Review |
| Final Report | September 23, 2025 |
| New Version Final Report | October 8, 2025 |
| Initial Commit | 2e57c08c0f |
| Final Commit | d21f1a9402 |
| New Version Initial Commit | 024ff6ef3d |
| New Version Final Commit | 522f247c7c |
| Documentation Assessment | High |
| Test Suite Assessment | High |
Findings by severity
| # | Contract | LoC | Comments | Ratio | Blank | Total |
| 1 | GenesisVaultManager.sol | 170 | 129 | 75.9% | 62 | 361 |
| 2 | RoleRegistry.sol | 41 | 22 | 53.7% | 14 | 77 |
| 3 | Base.sol | 40 | 6 | 15.0% | 10 | 56 |
| 4 | StakingVault.sol | 55 | 15 | 27.3% | 18 | 88 |
| 5 | VHYPE.sol | 15 | 2 | 13.3% | 4 | 21 |
| 6 | interfaces/IStakingVault.sol | 17 | 28 | 164.7% | 14 | 59 |
| 7 | interfaces/ICoreWriter.sol | 4 | 1 | 25.0% | 1 | 6 |
| 8 | libraries/CoreWriterLibrary.sol | 42 | 24 | 57.1% | 10 | 76 |
| 9 | libraries/Converters.sol | 10 | 3 | 30.0% | 3 | 16 |
| 10 | libraries/L1ReadLibrary.sol | 218 | 3 | 1.4% | 32 | 253 |
| Total | 612 | 233 | 38.1% | 168 | 1013 |
The new version includes file StakingVaultManager.sol which was introduced in the place of GenesisVaultManager.sol.
| # | Contract | LoC | Comments | Ratio | Blank | Total |
| 1 | StakingVaultManager.sol | 388 | 236 | 60.8% | 157 | 781 |
| Total | 388 | 236 | 60.8% | 157 | 781 |
Additionally, the new version introduced the following number of line changes to existing files:
| # | Contract | Changed LoC |
| 1 | RoleRegistry.sol | 4 |
| 2 | StakingVault.sol | 82 |
| 3 | VHYPE.sol | 11 |
The Ventuals LST protocol is a multi-contract system designed to operate across two distinct layers of the Hyperliquid network.
The main data flow involves HYPE tokens moving from a user's wallet on HyperEVM to the StakingVault contract, then being bridged to HyperCore where they are delegated to validators. Staking rewards accumulated on HyperCore, increasing the total HYPE held by the vault, which in turn appreciates the value of the vHYPE token.

Below is an overview of smart contracts and their functionality in the protocol.
4.1.1 GenesisVaultManager
4.1.2 vHYPE
4.1.3 StakingVault
4.1.4 RoleRegistry
4.2.1 User Deposit
4.2.2 HYPE Delegation
4.2.3 Reward Accumulation
Since the initial audit, the Ventuals LST protocol has undergone significant architectural changes that transform the system capabilities and user experience. The most notable change is the complete replacement of the GenesisVaultManager with a new StakingVaultManager contract, which introduces a batch-based withdrawal system and removes several previous limitations.
4.3.1 StakingVaultManager (Replaces GenesisVaultManager)
4.3.2 New Withdrawal Architecture
4.3.3 Updated Flow
User Deposit (Simplified)
StakingVaultManager.deposit() with HYPE.User Withdrawal (New Process)
queueWithdraw() with the desired vHYPE amount.processBatch().finalizeBatch(), which nets deposits and withdrawals.claimWithdraw().HYPE Delegation (Enhanced)
The risk rating methodology used by Nethermind Security follows the principles established by the OWASP Foundation. The severity of each finding is determined by two factors: Likelihood and Impact.
Likelihood measures how likely the finding is to be uncovered and exploited by an attacker. This factor will be one of the following values:
When defining the likelihood of a finding, other factors are also considered. These can include but are not limited to motive, opportunity, exploit accessibility, ease of discovery, and ease of exploit.
Impact is a measure of the damage that may be caused if an attacker exploits the finding. This factor will be one of the following values:
When defining the impact of a finding, other factors are also considered. These can include but are not limited to data and state integrity, loss of availability, financial loss, and reputation damage. After defining the likelihood and impact of an issue, the severity is determined according to the table below.
| Impact / Likelihood | Low | Medium | High |
| High | Medium | High | Critical |
| Medium | Low | Medium | High |
| Low | Info / Best Practices | Low | Medium |
| Undetermined | Undetermined | Undetermined | Undetermined |
To address issues that do not fit a High, Medium or Low severity, Nethermind Security also uses three more finding severities: Informational, Best Practices, and Undetermined.
| File | Fix commit | Type | Status |
src/GenesisVaultManager.solsrc/StakingVault.sol | 9007e61f5da506 | High | Fixed |
The HYPETovHYPE function in the GenesisVaultManager contract is vulnerable to an inflation attack due to exchange rate manipulation. The exchange rate is calculated as totalHYPE / totalVHYPE, which can be artificially inflated by donating directly to the vault without minting corresponding shares.
An attacker can exploit this by: (1) depositing a minimal amount (1 wei) to receive 1 vHYPE share, (2) donating a large amount (e.g., 10 ETH) directly to the staking vault via the receive() function, (3) inflating the exchange rate to approximately (10 ETH * 1e18) / 1 wei ≈ 10^22, and (4) causing victim deposits to result in 0 vHYPE shares due to integer division truncation when hypeAmount * 1e18 < _exchangeRate in the Math.mulDiv(hypeAmount, 1e18, _exchangeRate) calculation.
This allows the attacker to gain control of all vault assets with minimal investment while legitimate depositors receive 0 vHYPE shares despite depositing significant amounts, resulting in a complete loss of funds for victims and making the vault unusable for legitimate users.
Recommendation
Use internal accounting to keep track of all the HYPE in the vault with a storage variable and update it when the contract receives HYPE instead of using .balance.
Resolution
Fixed by 9007e61d16 and f5da5068c2
| File | Fix commit | Type | Status |
src/GenesisVaultManager.solsrc/StakingVault.sol | a02ad2a | High | Fixed |
On depositing Hype tokens into the GenesisVaultManager contract, the tokens are moved into the StakingVault. At this time, the vHype tokens are minted for the accepted amount.
From the StakingVault, the manager can transfer Hype to any other account by calling the transferHype function, which will move the funds out of the protocol.
While Hype tokens are taken out of the protocol, the extent of vHype is not burnt.
While computing the exchange rate, the totalBalance for Hype comprises staking Balance + Spot Balance + funds in the StakingVault contract.
function exchangeRate() public view returns (uint256) {
==> uint256 balance = totalBalance();
==> uint256 totalSupply = vHYPE.totalSupply();
//....
return Math.mulDiv(balance, 1e18, totalSupply);
}As the vHype was not burnt when taking out funds from StakingVault, it will directly impact the exchange rate.
Recommendation
Consider removing the transferHype function or burn equivalent vHYPE shares on transfer.
Resolution
Removed the transferHype function a02ad2aa62
| File | Fix commit | Type | Status |
src/GenesisVaultManager.sol | 9007e61 | Medium | Fixed |
The system suffers from decimal conversion loss when handling HYPE deposits due to the conversion between 18 decimals (EVM standard) and 8 decimals (HyperCore standard).
The Converters.to8Decimals() function performs a division by 1e10 to convert from 18 decimals to 8 decimals: This division operation truncates any remainder less than 1e10 wei, resulting in permanent loss of precision. For example:
1.0000000001 HYPE (1e18 + 100 wei) would be converted to 1 HYPE (1e8) on HyperCore;1.0000000000 HYPE (1e18), losing the original 100 wei;Recommendation
Enforce minimum deposit granularity by a validation in the deposit() function to ensure only multiples of the minimum precision unit can be deposited (amountToDeposit % 1e10 == 0). Besides, add a minimum deposit amount check to prevent dust deposits that would result in significant relative precision loss.
Resolution
Added minimum deposit constraint 9007e61d1
| File | Fix commit | Type | Status |
src/GenesisVaultManager.solsrc/StakingVault.sol | 6c4f718 | Medium | Fixed |
In the StakingVault there are functions that interact with HyperCore. For the actions performed on HyperCore, the updated state does not reflect during reads via pre-compiled contracts until the next block. Hence, any read before the formation of the next block could result in incorrect values.
Currently, in order to prevent such a read, the tracking variable for the last action is in the GenesisVaultManager contract. If the manager role is configured for GenesisVaultManager and another EOA account, there is a possibility for EOA to interact with HyperCore in the StakingVault, resulting in changes to HyperCore state in transit.
For example, considering HYPE can be deposited directly into the StakingVault, if the intent is to send those funds to any of the below actions interacting with HyperCore, it will impact the working of the protocol.
function tokenDelegate(address validator, uint64 weiAmount, bool isUndelegate) external onlyManager whenNotPaused {
CoreWriterLibrary.tokenDelegate(validator, weiAmount, isUndelegate);
}
/// @inheritdoc IStakingVault
function spotSend(address destination, uint64 token, uint64 weiAmount) external onlyManager whenNotPaused {
CoreWriterLibrary.spotSend(destination, token, weiAmount);
}
/// @inheritdoc IStakingVault
function transferHypeToCore(uint256 amount) external onlyManager whenNotPaused {
_transfer(payable(HYPE_SYSTEM_ADDRESS), amount);
}As the protection implemented in GenesisVaultManager is not effective in StakingVault, it could result in incorrect exchange rates.
Recommendation
Consider enforcing the Manager role to GenesisVaultManager during the genesis phase which is the intent. An improvement to consider is to move the _transferToCoreAndDelegate internal function into StakingVault so that interactions between stakingVault and HyperCore will be effective even after the genesis phase.
Resolution
As discussed, moved the lastEvmToCoreTransferBlockNumber logic to StakingVault so that the one-block delay is enforced in the StakingVault. 6c4f718eff
| File | Fix commit | Type | Status |
src/GenesisVaultManager.sol | 0d6903e | Low | Fixed |
GenesisVaultManager can accept Hype tokens directly as the contract implements receive and fallback functions. While the Hype accepted via deposit function, equivalent vHype is minted and tokens are moved to the stakingVault, the directly deposited will remain in the GenesisVaultManager contract.
As there is no function to withdraw the hype tokens from GenesisVaultManager contract, any deposits directly sent to the contract will be stuck and locked forever.
Recommendation
Consider removing the receive and fallback functions
Resolution
Removed the receive and fallback functions 0d6903e09914
| File | Fix commit | Type | Status |
src/GenesisVaultManager.solsrc/VHYPE.sol | 5d78a55 | Low | Fixed |
User can deposit Hype tokens into GenesisVaultManager contract, against which he will receive VHYPE tokens. The user can burn his vHYPE tokens at his discretion by calling burn on the Token contract.
Burning the token will impact the totalSupply as the supply will reduce to the extent of tokens burnt. This will directly inflate the value of VHYPE tokens.
Recommendation
Consider removing the burn function.
Resolution
Not a bug per-se, since if a user intentionally burned their tokens, the exchange rate *should* get inflated. There isn't a way for an attacker to exploit this, since they would just end up losing their claim on the underlying HYPE in the net.
However, we discussed removing this burn function to avoid accidental burns and reduce the surface area of bugs. Removed in this PR 5d78a553ac7
| File | Fix commit | Type | Status |
src/VHYPE.sol | 5d4a5c7 | Low | Fixed |
The Base contract has a whenNotPaused modifier that is used to prevent certain actions when the contract is paused. The VHYPE contract inherits from Base and has a mint function. The mint function does not have whenNotPaused and hence VHYPE tokens can be minted even when VHYPE contract is paused.
function mint(address to, uint256 amount) public onlyManager {
_mint(to, amount);
}Recommendation
Consider adding the whenNotPaused modifier to the mint function. This would prevent new tokens from being minted when the contract is paused, ensuring consistent behavior across both public and internal minting methods.
Resolution
Added whenNotPaused to mint() 5d4a5c7e88d
| File | Fix commit | Type | Status |
src/GenesisVaultManager.sol | 9007e61 | Info | Fixed |
The deposit function can be called with 0 HYPE. As the deposit function does not check for msg.value to be greater than 0, the function will execute and generate a deposit event while consuming gas.
function deposit() public payable canDeposit whenNotPaused {
uint256 requestedDepositAmount = msg.value;// if msg.value is 0
//...
==> emit Deposit(
msg.sender, /* depositor */
amountToMint, /* minted */
amountToDeposit, /* deposited */
requestedDepositAmount - amountToDeposit /* refunded */
);
}Recommendation
Consider adding a validation for msg.value to be greater than 0 or preferably a minimum deposit amount.
Resolution
Fixed by minimum deposit limits 9007e61d162
| File | Fix commit | Type | Status |
src/lib/CoreWriterLibrary.sol | 608e7fd | Info | Fixed |
The CoreWriterLibrary contract contains an inconsistent comment that states that weiAmount should be converted to 6 decimals before being passed to its functions. However, the rest of the protocol, including the GenesisVaultManager contract and the function-level Natspec comments, consistently uses 8 decimals for HYPE amounts sent to HyperCore. This discrepancy can lead to confusion.
The misleading comment is found in the contract-level NatSpec as below.
/// All weiAmounts must be converted to 6 decimals before calling these functions.
// ...
library CoreWriterLibrary {
// ...
}Recommendation
Consider updating the CoreWriterLibrary contract's NatSpec comment to reflect the correct decimal conversion
Resolution
Fixed 608e7fd69e4
| File | Fix commit | Type | Status |
src/GenesisVaultManager.sol | f045057 | Info | Fixed |
In the GenesisVaultManager contract, the funds moved to the HyperCore are delegated to a defaultVault.
The delegations to a particular validator have a lockup period of 1 day. Only after this lockup, delegations may be partially or fully undelegated at any time.
In the current implementation, the funds are delegated to the defaultVault.
If there arises a scenario where there is a need for emergencyStakingWithdraw, the earliest undelegate request can be submitted only after passing of 1 day from the last deposit.
function emergencyStakingWithdraw(uint256 amount, string calldata purpose) external onlyOwner {
//...
==> // Immediately undelegate HYPE
// @audit, the undelagate can be called 1 day after
// the last deposit.
stakingVault.tokenDelegate(defaultValidator, amount.to8Decimals(), true);
//...
}Recommendation
Consider error handling in case emergencyStakingWithdraw does not work due to recent delegation to the validator.
Resolution
Addressed in this f045057de3
| File | Fix commit | Type | Status |
src/GenesisVaultManager.sol | 19c95b5 | Info | Fixed |
When setting the whitelistDepositLimit for an address, the limit should be greater than the current defaultDepositLimit.
function setDefaultDepositLimit(uint256 _defaultDepositLimit) public onlyOwner {
defaultDepositLimit = _defaultDepositLimit;
}
function setWhitelistDepositLimit(address depositor, uint256 limit) public onlyOwner {
whitelistDepositLimits[depositor] = limit;
}Recommendation
Consider adding a validation to check the limit to be greater than defaultDepositLimit.
Resolution
Going to leave behavior as-is, but updated the comment to avoid confusion 19c95b5798
| File | Fix commit | Type | Status |
src/Base.sol* | 0231aee | Best Practices | Fixed |
The protocol implements a Base contract using UUPS upgradeable proxy pattern. The common functionality is implemented in the Base contract, which is extended by other contracts in the protocol.
As the protocol follows the traditional storage for state, the storage layout is defined. In the future, if the Base contract needs to be extended to support more common features with state, it will not be possible. The absence of storage gaps removes the flexibility to insert variables in future upgrades without causing storage collisions.
Recommendation
Consider adding storage gaps to provision future extension in functionality.
Resolution
Fixed 0231aee978de
| File | Fix commit | Type | Status |
StakingVaultManager.sol | — | Critical | Fixed |
The function claimWithdraw() performs following checks:
function claimWithdraw(uint256 withdrawId, address destination) public whenNotPaused {
Withdraw storage withdraw = withdraws[withdrawId];
require(msg.sender == withdraw.account, NotAuthorized());
require(!withdraw.cancelled, WithdrawCancelled());
require(!withdraw.claimed, WithdrawClaimed());
Batch memory batch = batches[withdraw.batchIndex];
require(block.timestamp > batch.finalizedAt + 7 days, WithdrawUnclaimable()); // TODO: Should we add a buffer?
uint256 withdrawExchangeRate = batch.slashed ? batch.slashedExchangeRate : batch.snapshotExchangeRate;
uint256 hypeAmount = _vHYPEtoHYPE(withdraw.vhypeAmount, withdrawExchangeRate);
...
}The function, however, does not check if the withdraw.batchIndex is not type(uint256).max. Also, the requirement block.timestamp > batch.finalizedAt + 7 days does not take into consideration that batch.finalizedAt with value 0 would pass. When the request is processed but the batch is not finalised, the request would contain the current batchIndex and the batch would contain snapshotExchangeRate, but the finalizedAt would be 0. This allows users to claim funds at the snapshotExchangeRate without the 7-day waiting period. In consequence, the calculations in the protocol would be incorrect, leading to loss of funds.
Recommendation
Consider preventing claiming in waiting period by checking if the withdraw.batchIndex is not type(uint256).max and that batch.finalizedAt is not 0.
Resolution
Fixed 8def0bb
burnFrom()| File | Fix commit | Type | Status |
VHYPE.sol | — | Medium | Fixed |
The burnFrom() function in VHYPE does not contain the pause check.
Recommendation
Consider introducing the pause check to VHYPE.burnFrom().
Resolution
Fixed 92b7aeb
| File | Fix commit | Type | Status |
StakingVaultManager.sol | — | Medium | Fixed |
The function queueWithdraw() allows user to request withdrawal of any amount of vHYP greater than 0. A malicious user can create requests with a small amount of vHYPE to temporarily DOS the batch finalisation. The finalisation can only be done if there are no withdrawal requests in the queue that could be fulfilled with available funds, which is checked in _canFinalizeBatch(). A malicious user could create a withdrawal request with a small amount before the finalisation, to add another request that can be fulfilled, effectively stopping the finalisation. Moreover, users could add many small-value requests to disincentivise calling processBatch() due to high gas cost.
Recommendation
Consider defining minimum withdrawal request value.
Resolution
| File | Fix commit | Type | Status |
StakingVault.solStakingVaultManager.sol | — | Medium | Fixed |
The stake and tokenRedelegate functions do not validate validator addresses. They will not fail with validator == address(0) or any invalid address, which could lead to silent errors since the functions will not revert but may fail silently during delegation operations.
Recommendation
Add validation to ensure validator addresses are not zero addresses and consider implementing a whitelist of allowed validators.
Resolution
Fixed 39e9bc8
| File | Fix commit | Type | Status |
StakingVaultManager.sol | — | Medium | Fixed |
Users can request withdrawal of any amount. The requests are processed in a queue. Withdrawn amount is limited by the HyperCore staking restriction, at least 500k HYPE tokens (initially) must be staked to maintain the perpetuals DEX deployment. This is checked in StakingVaultManager with minimumStakeBalance in the processBatch() function. However, there is a scenario where a single user requests a huge amount of tokens to withdraw. In such a case, there must be enough funds available to process the request of that user and all the subsequent requests. If that amount is really high, the withdrawals may be blocked for a substantial amount of time.
Recommendation
Consider introducing maximum limit for withdrawal request. This would incentivise users to withdraw in smaller portions and allow continuous withdrawals.
Resolution
Fixed 582641b. The fix is implemented such that we will automatically split a large withdraw request into smaller withdraws
| File | Fix commit | Type | Status |
StakingVaultManager.sol | — | Medium | Fixed |
When the slashing happens, admins of the vHype protocol call the applySlash(). However, if this function is applied too late, users can claim the withdrawal funds from the affected batches. This may result in two problems:
totalHypeClaimed is increased, but the applySlash() adjusts only the totalHypeProcessed according to the new slashedExchangeRate. This may result in totalHypeClaimed > totalHypeProcessed which would cause revery in totalBalance() since reservedHypeForWithdraws = totalHypeProcessed - totalHypeClaimed would result in underflow;Note that the expected scenario is that the admins would react immediately to the slash event and call applySlash() only on the affected batches.
Recommendation(s): To ensure that no claiming happens between the actual slash event and calling applySlash(), consider introducing a two-step mechanism, which would first apply the slash or not, and only after allow claiming.
Resolution
Fixed ee2d169
| File | Fix commit | Type | Status |
StakingVaultManager.sol | — | Medium | Fixed |
The truncation is not applied during the transfer of funds to the spot account in finaliseBatch(). This results in potential loss of 1e10 wei during every deposit.
function finalizeBatch() external whenNotPaused whenBatchProcessingNotPaused {
...
// Always transfer the full deposit amount to HyperCore spot
if (depositsInBatch > 0) {
stakingVault.transferHypeToCore(depositsInBatch);
}
...
}The depositsInBatch will be truncated during transfer to HyperCore, but the whole un-truncated amount will be deducted from the StakingVault.
Recommendation
Consider applying restriction of precision less or equal to 1e8. This can be applied by adding a check to enforce amount % 1e10 == 0.
Resolution
Fixed 66961ad
| File | Fix commit | Type | Status |
StakingVaultManager.sol | — | Low | Fixed |
When claimWithdraw is called for a withdrawal that hasn't been processed yet (batchIndex is still type(uint256).max), the function doesn't fail early with a clear error message. Instead, it proceeds through all validation checks and only fails when reaching spotSend() because the balance will be 0, resulting in an unclear error message that doesn't indicate the withdrawal hasn't been processed yet.
Recommendation
Add explicit validation to check that withdraw.batchIndex != type(uint256).max in claimWithdraw and provide a clear error message if the withdrawal hasn't been processed yet.
Resolution
Fixed 8def0bb
| File | Fix commit | Type | Status |
StakingVaultManager.sol | — | Low | Fixed |
The validation checks for Core user existence and spot balance are performed in StakingVaultManager::claimWithdraw() before calling StakingVault::spotSend(). These checks should be moved to the StakingVault::spotSend() function to ensure that if/when StakingVaultManager is upgraded, the essential validation checks are still in place since they are critical for StakingVault functionality.
Recommendation
Move the Core user existence and spot balance validation checks to the StakingVault::spotSend() function to centralize validation logic.
Resolution
| File | Fix commit | Type | Status |
StakingVault.sol | — | Info | Fixed |
The timing constraint logic uses block.number > lastDelegationChangeBlockNumber[_validator] + 1 in the block number comparison, but it's unclear why this additional block is required. This creates inconsistency with other timing checks in the contract that don't use + 1 like in the deposit function, where we have block.number > lastEvmToCoreTransferBlockNumber.
Recommendation
Clarify the reasoning for the + 1 requirement in the documentation or remove it for consistency.
Resolution
Fixed b59f8a9
| File | Fix commit | Type | Status |
StakingVaultManager.sol | — | Info | Fixed |
Increasing minimumStakeBalance after processing a batch but before finalization can temporarily prevent batch finalization if the new minimum makes balance < minimumStakeBalance + hypeProcessed. However, this can be resolved by lowering minimumStakeBalance again or using the resetBatch function.
Recommendation
Consider adding a check in the setMinimumStakeBalance function to ensure that the new minimum is not greater than the current balance if a batch is already processing.
Resolution
Fixed 65102fd
| File | Fix commit | Type | Status |
StakingVaultManager.sol | — | Best Practices | Fixed |
There are two time checks in the manager: (1) a 7-day withdrawal queue and (2) a 1-day unstake lockup after stake. Those checks mirror the mechanisms on HyperCore. It is recommended to increase those checks slightly to ensure that the calls won't result in silent failures, which may cause loss of funds.
Recommendation
Consider increasing time checks to ensure correct behaviour. Additionally, consider increasing the block separation time to be greater than 1.
Resolution
Fixed d7fea7e
Software documentation refers to the written or visual information that describes the functionality, architecture, design, and implementation of software. It provides a comprehensive overview of the software system and helps users, developers, and stakeholders understand how the software works, how to use it, and how to maintain it. Software documentation can take different forms, such as user manuals, system manuals, technical specifications, requirements documents, design documents, and code comments. Software documentation is critical in software development, enabling effective communication between developers, testers, users, and other stakeholders. It helps to ensure that everyone involved in the development process has a shared understanding of the software system and its functionality. Moreover, software documentation can improve software maintenance by providing a clear and complete understanding of the software system, making it easier for developers to maintain, modify, and update the software over time. Smart contracts can use various types of software documentation. Some of the most common types include:
These types of documentation are essential for smart contract development and maintenance. They help ensure that the contract is properly designed, implemented, and tested, and they provide a reference for developers who need to modify or maintain the contract in the future.
The Ventuals protocol documentation provides a comprehensive overview of the liquid staking token (LST) system built on Hyperliquid. The documentation effectively covers both the current implementation (Phase 1) and future planned features (Phase 2), providing appropriate context for the current audit. The team provided an overview of the main system components during the kick-off call with a detailed explanation of the intended functionalities and was responsive to questions during the review.
All the relevant issues raised by the AuditAgent have been incorporated into this report. The AuditAgent is an AI-powered smart contract auditing tool that analyses code, detects vulnerabilities, and provides actionable fixes. It accelerates the security analysis process, complementing human expertise with advanced AI models to deliver efficient and comprehensive smart contract audits. Available at https://app.auditagent.nethermind.io.
| 234Tests passed | 0Failed |
The complete test output is in the full report.
As auditors, we recommend that any changes or updates made to the audited codebase undergo a re-audit or security review to address potential vulnerabilities or risks introduced by the modifications. By conducting a re-audit or security review of the modified codebase, you can significantly enhance the overall security of your system and reduce the likelihood of exploitation. However, we do not possess the authority or right to impose obligations or restrictions on our clients regarding codebase updates, modifications, or subsequent audits. Accordingly, the decision to seek a re-audit or security review lies solely with you.
This report is based on the scope of materials and documentation provided by you to Nethermind in order that Nethermind could conduct the security review outlined in 1. Executive Summary and 2. Audited Files. The results set out in this report may not be complete nor inclusive of all vulnerabilities. Nethermind has provided the review and this report on an as-is, where-is, and as-available basis. You agree that your access and/or use, including but not limited to any associated services, products, protocols, platforms, content, and materials, will be at your sole risk. Blockchain technology remains under development and is subject to unknown risks and flaws. The review does not extend to the compiler layer, or any other areas beyond the programming language, or other programming aspects that could present security risks. This report does not indicate the endorsement of any particular project or team, nor guarantee its security. No third party should rely on this report in any way, including for the purpose of making any decisions to buy or sell a product, service or any other asset. To the fullest extent permitted by law, Nethermind disclaims any liability in connection with this report, its content, and any related services and products and your use thereof, including, without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement. Nethermind does not warrant, endorse, guarantee, or assume responsibility for any product or service advertised or offered by a third party through the product, any open source or third-party software, code, libraries, materials, or information linked to, called by, referenced by or accessible through the report, its content, and the related services and products, any hyperlinked websites, any websites or mobile applications appearing on any advertising, and Nethermind will not be a party to or in any way be responsible for monitoring any transaction between you and any third-party providers of products or services. As with the purchase or use of a product or service through any medium or in any environment, you should use your best judgment and exercise caution where appropriate. FOR AVOIDANCE OF DOUBT, THE REPORT, ITS CONTENT, ACCESS, AND/OR USAGE THEREOF, INCLUDING ANY ASSOCIATED SERVICES OR MATERIALS, SHALL NOT BE CONSIDERED OR RELIED UPON AS ANY FORM OF FINANCIAL, INVESTMENT, TAX, LEGAL, REGULATORY, OR OTHER ADVICE.
The Leading Engineers of Blockchain Infrastructure