Venus Protocol security record

BNB Chain, Ethereumvenus.ioX

As of 30 Oct 2026, Venus Protocol has 67 audit reports by 7 security firms on Trustblock; the latest is by Quantstamp, dated 13 Sep 2025. Those reports list no open critical findings. It also holds 2 deployed contracts on 2 chains and 2 incidents (latest 12 May 2022).

Critical findings
No open critical findings
Across the 67 reports, 4 critical findings were reported. Each is marked fixed by the firm that reported it. See the findings
Incident
Incident 12 May 2022
Source: De.Fi incident database. 63 audits have been published since. See the incidents
Open the latest report
Your label, live
Get the label for your site

Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.

Audits67

Newest first

67 audit reports, 40 in CertiK’s series, 11 in Quantstamp’s series

AuditSecurity firmDateScopeCritical findingsReport
Venus - Vaults AuditSecurity firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com
Venus - Liquidator ContractSecurity firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com
Venus / Lending PlatformSecurity firm: HackenDate: Scope: Files named in the reportNo open critical findingsOpen · hacken.io
Venus / DEXSecurity firm: HackenDate: Scope: Files named in the report1 critical finding, fixedOpen · hacken.io
Venus Protocol SwapRouter AuditSecurity firm: OpenZeppelinDate: Scope: Files named in the reportNo open critical findingsOpen · blog.openzeppelin.com
Venus - Isolated PoolsSecurity firm: CertiKDate: Scope: Files named in the report1 critical finding, fixedOpen · skynet.certik.com
Venus Protocol Oracles AuditSecurity firm: OpenZeppelinDate: Scope: Files named in the reportNo open critical findingsOpen · blog.openzeppelin.com
Venus protocol (vaults)Security firm: QuantstampDate: Scope: Repository at commit f1426f0No open critical findingsOpen · certificate.quantstamp.com
Venus - VAI PegSecurity firm: CertiKDate: Scope: Files named in the report1 critical finding, fixedOpen · skynet.certik.com
Venus - Swap RouterSecurity firm: CertiKDate: Scope: Files named in the report1 critical finding, fixedOpen · skynet.certik.com
Venus - OracleSecurity firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com
Venus / OracleSecurity firm: HackenDate: Scope: Files named in the reportNo open critical findingsOpen · hacken.io
Venus / Lending PlatformSecurity firm: HackenDate: Scope: Files named in the reportNo open critical findingsOpen · hacken.io
Venus: Venus MintBehalf auditSecurity firm: PeckShieldDate: Scope: Not recorded (see the report)No open critical findingsOpen · GitHub
Venus: Venus Grant auditSecurity firm: PeckShieldDate: Scope: Not recorded (see the report)No open critical findingsOpen · GitHub
Venus auditSecurity firm: PeckShieldDate: Scope: Not recorded (see the report)No open critical findingsOpen · GitHub
Swipe Venus ProtocolSecurity firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com

Findings426

Statuses are the security firm’s own, from each report.

SeverityOpenAcknowledgedFixed
Critical003
High16013
Medium5432
Low7160222
HighCentralization Related RisksVenus - RiskOracle Integration · CertiK · 19 Feb 2025Open

Note that any centralization risks present in the existing codebase before the PR's in scope of this audit were not considered. Only those added to the in-scope PRs are addressed. We recommend all users carefully review the centralization risks, much of which can be found in our previous audits, which can be found here: [https://skynet.certik.com/projects/venus](https://skynet.certik.com/projects/venus). **MarketCapsRiskSteward** In the contract `MarketCapsRiskSteward`, the `DEFAULT_ADMIN_ROLE` of the `AccessControlManager` can grant addresses the privilege to call the function `setMaxDeltaBps()`. Any compromise to the `DEFAULT_ADMIN_ROLE` or accounts granted this privilege may allow the hacker to take advantage of this authority and set the max delta bps to a small non-zero value to prevent updates from process or to a large value to allow malicious updates to successfully process. --- In the contract `MarketCapsRiskSteward`, the `RISK_STEWARD_RECEIVER` has the privilege to call the function `processUpdate()`. Any compromise to the `RISK_STEWARD_RECEIVER` may allow the hacker to take advantage of this authority to process malicious supply and borrow cap updates. --- **RiskStewardReceiver** In the contract `MarketCapsRiskSteward`, the `DEFAULT_ADMIN_ROLE` of the `AccessControlManager` can grant addresses the privilege to call the following functions: - `pause()` - `unpause()` - `setRiskParameterConfig()` - `toggleConfigActive()` Any compromise to the `DEFAULT_ADMIN_ROLE` or accounts granted this privilege may allow the hacker to take advantage of this authority and do the following: - Pause the contract to cause a denial of service. - Unpause the contract to allow actions to be performed when they are not expected. - Set the risk parameter configuration for any update type, where they can set the `riskSteward` to any address and `debounce` to any non-zero value. This could be used to bypass important checks and to allow updates to be processed in quick succession. - Toggle a configuration for an update type. This can cause a denial of service if it is toggled off unexpectedly or allow an unintended configuration to be used if it is toggled on. --- In addition, some of the aliased functions in the adjustment to the core comptroller were privileged functions. The entities that have access to the original privileged function also have access to the aliased privileged function. However, as the functions are simply aliases, they hold the same power.

Open the report
HighContract Upgrade Centralization RiskVenus - RiskOracle Integration · CertiK · 19 Feb 2025Open

The contracts `MarketCapsRiskSteward` and `RiskStewardReceiver` are upgradeable; the corresponding `admin` role in each respective proxy has the authority to update the implementation contract behind each contract. Any compromise to the `admin` account in each proxy may allow a hacker to take advantage of this authority and change the implementation contract the proxy points to, and therefore execute potential malicious functionality in the implementation contract.

Open the report
HighCentralization Risks in RiskFundV2.solVenus - Risk Fund Upgrade · CertiK · 26 Aug 2024Open

Note that any centralization risks present in the existing codebase before the PR's in scope of this audit were not considered. Only those added to the in-scope PRs are addressed. We recommend all users carefully review the centralization risks, much of which can be found in our previous audits, which can be found here: [https://skynet.certik.com/projects/venus](https://skynet.certik.com/projects/venus). In the contract `RiskFundV2` the `DEFAULT_ADMIN_ROLE` of the `AccessControlManager` can grant addresses the privilege to call the function `sweepTokenFromPool()`. Any compromise to the `DEFAULT_ADMIN_ROLE` or accounts granted this privilege may allow the hacker to take advantage of this authority and remove any amount of any token from the contract, sending it to an address they control.

Open the report
HighCentralization Related RisksVenus - sfrxETH oracle adapter · CertiK · 17 May 2024Open

In the contract `SFrxETHOracle`, the role `DEFAULT_ADMIN_ROLE` of the `AccessControlManager` can grant addresses the privilege to call the following functions: - `setMaxAllowedPriceDifference()` Any compromise to the `DEFAULT_ADMIN_ROLE` or accounts granted this privilege may allow a hacker to take advantage of this authority and do the following: - Increase or decrease the allowed price difference to cause a denial of service or enable larger price fluctuations.

Open the report
HighCentralized Control of Contract UpgradeVenus - sfrxETH oracle adapter · CertiK · 17 May 2024Open

`SFrxETHOracle` is an upgradeable contract, the owner can upgrade the contracts at any time. If an attacker compromises the owner, they can change the implementation of the contract to return any price they wish for the asset to steal funds from the protocol.

Open the report
HighCentralization Risks in NativeTokenGateway.solVenus - redeemAndUnwrap · CertiK · 19 Mar 2024Open

In the contract `NativeTokenGateway` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and remove the entire balance of native token or any ERC20 token from the contract and send it to their own address. It is noted that the contract is not intended to hold tokens in normal cases. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-e2ea-cd2c9620-8142-47f31fde2372/diagrams/centralization_NativeTokenGateway-NativeTokenGateway-_owner.svg)

Open the report
HighCentralization Risks in Liquidator.solVenus - Liquidator Contract · CertiK · 4 Jul 2023Open

In the contract `Liquidator` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and change the `_accessControlManager` which can allow them to give any of the privledges outline below or the `protocolShareReserve` to collect the protocols share for themselves. ![](https://accelerator-tasks-prod.acc.corp.certik.com/952fa6d1d44541c8b65e9ea5ede8f9dc/diagrams/centralization_Liquidator-Liquidator-_owner.svg) --- In the contract `Liquidator`, the `_accessContolManager` contract can give privilege to the following functions: - `restrictLiquidation()`, which can be used to prevent a borrower from being liquidated by having no liquidators on their allowlist. - `unrestrictLiquidation()`, which can be used to allow a non-allowlisted user to liquidate an account. - `addToAllowlist()`, which can allow any address to liquidate an account. - `removeFromAllowlist()`, which can remove an liquidators ability to liquidate an account. If all liquidators are removed from a borrowers allowlist this will make it so they cannot be liquidated. - `setTreasuryPercent()`, which can be set so that the protocol share reserve receives none of the liquidation incentive. Or it can be set so that it receives all of the liquidation incentive. - `setMinLiquidatableVAI()`, which can be set to a small value so that a liquidator would always need to liquidate VAI before they could liquidate any other borrows. - `setPendingRedeemChunkLength()`, which can be set to a large value and cause a denial of service if the `pendingRedeem` array is too large. Or set to zero to prevent any tokens pending redemption from being redeemed. - `pauseForceVAILiquidate()`, which can be used to not have to liquidate VAI borrows before others. - `resumeForceVAILiquidate()`, which can be used to ensure that VAI borrows are liquidated before any others.

Open the report
HighCentralized Control of Contract UpgradeVenus - Liquidator Contract · CertiK · 4 Jul 2023Open

`Liquidator.sol` is an upgradeable contract. The owner can upgrade the contract without the community's commitment. If an attacker compromises the account, he can change the implementation of the contract and drain tokens from the contract.

Open the report
HighUnverifiable LogicVenus / DEX · Hacken · 24 Jun 2023Open

The report gives no description here.

Open the report
HighCentralization Related RisksVenus - VAI Peg · CertiK · 24 May 2023Open

### PegStability.sol In the contract `PegStability` the `DEFAULT_ADMIN_ROLE` can grant access to the following functions: - `pause()` - `resume()` - `setFeeIn()` - `setFeeOut()` - `setVaiMintCap()` - `setVenusTreasury()` - `setComptroller()` Any compromise to the `DEFAULT_ADMIN_ROLE` or access to the functions may allow a hacker to do the following - Pause the contract preventing anyone from swapping. - Resume the contract, which may allow swaps to occur when the should not be allowed. - Set the fees in BIPs to any percentage less than 100%. - Set the `vaiMintCap` to any value, allowing any amount of VAI to be minted or if the value is set to 0 to prevent anyone swapping stable token to VAI. - Set the treasury to a wallet they control to collect the fees for themselves. - Set the comptroller address to a malicious contract that will return the address of a malicious oracle to provide inaccurate prices for the stable token.

Open the report
Show 10 more
HighCentralized Control of Contract UpgradeVenus - VAI Peg · CertiK · 24 May 2023Open

`PegStability` is an upgradeable contract. The owner can upgrade the contract without the community's commitment. If an attacker compromises the account, they can change the implementation of the contract and drain tokens from the contract.

Open the report
HighCentralization Risks in SwapRouter.solVenus - Swap Router · CertiK · 22 May 2023Open

In the contract `SwapRouter` the role `WBNB` has authority to send `BNB` to the contract. If it is set to a malicious contract, then it can allow an attacker to send `BNB` to the contract. This is an immutable variable and `WBNB` is not an upgradeable contract, so this only needs to be checked once after deployment to be the correct address. In the contract `SwapRouter` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and do the following: - transfer any tokens held by the contract to any other address; - set the `vBNBAddress` to any other listed `vToken`, which would revert or if the comptroller is compromised could be set to a malicious contract. ![](https://accelerator-tasks-prod.acc.corp.certik.com/fd5ad38b5da54f6d837e7c86385d331a/diagrams/centralization_SwapRouter-SwapRouter-_owner.svg)

Open the report
HighHighly Permissive Role AccessVenus / Lending Platform · Hacken · 1 Apr 2023Open

The report gives no description here.

Open the report
HighCentralization Related RisksOpen

### TimelockV8 In the contract `TimelockV8` the role `admin` has authority over the functions shown in the diagram below. Any compromise to the `admin` account may allow the hacker to take advantage of this authority and do the following: - Queue a malicious transaction. - Cancel a transaction causing it to have to be queued again. - Execute a transaction when it was not intended to be or execute a malicious transaction they had previously queued. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-afca-b0345ba0-a4a2-59c3fa4258b2/diagrams/centralization_TimelockV8-TimelockV8-admin.svg) In addition to this, they also have control over the following functions which can only be called by queueing a transaction that will call them and then executing that transaction: - `setDelay()` - `setPendingAdmin()` Any compromise to the `admin` account may allow a hacker to queue and then execute a transaction that will change the delay between the MINIMUM_DELAY and MAXIMUM_DELAY. It will also allow them to set the pending admin to an account they control, which can then call `acceptAdmin()` so that the team cannot recover the role from the hacker. --- ### BaseOmnichainControllerSrc In the contract `BaseOmnichainControllerSrc` the `DEFAULT_ADMIN_ROLE` of the `AccessControlManager` can grant addresses the privilege to call the following functions: - `setMaxDailyLimit()` - `pause()` - `unpause()` Any compromise to the `DEFAULT_ADMIN_ROLE` or accounts granted this privilege may allow the hacker to take advantage of this authority and do the following: - Update the max daily receive limit to 0 in order to prevent sending any proposals, or set it to a high value to allow more proposals to be sent than intended. - Pause or unpause the contract during a crucial period. --- In the contract `BaseOmnichainControllerSrc`, the role `_owner` has authority over the following functions: - `setAccessControlManager()` Any compromise to the `_owner` account may allow a hacker to take advantage of this authority and update the `accessControlManager` address to a malicious contract and gain control over setting the privilege of the functions above. --- ### BaseOmnichainControllerDest In the contract BaseOmnichainControllerDest, the role `_owner` has authority over the following functions: - `setMaxDailyReceiveLimit()`; - `pause()`; - `unpause()`; Any compromise to the `_owner` account may allow a hacker to take advantage of this authority and - Update the max daily receive limit to 0 in order to prevent receiving any proposals, or set it to a high value to allow more proposals to be accepted than intended. - Pause or unpause the contract during a crucial period. --- ### OmnichainExecutorOwner In the contract `OmnichainExecutorOwner` the role `_owner` has authority over the following functions: - `upsertSignature()` Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and make a function signature active within the `functionRegistry` mapping in order to give their account access to this Omnichain Governance logic through the privilege outlined below. --- In the contract `OmnichainExecutorOwner` the role `DEFAULT_ADMIN_ROLE` of the `AccessControlManager` can grant addresses the privilege to call the following functions: - Functions within the Omnichain Governance via the `fallback()` function in `OmnichainExecutorOwner` - `transferBridgeOwnership()` Any compromise to the `DEFAULT_ADMIN_ROLE` or accounts granted this privilege may allow the hacker to take advantage of this authority and do the following: - Call privileged functions that the `OmnichainExecutorOwner` controls within the Omnichain Governance. - Give an account they control the owner privilege of the bridge in order to access other functions so they can take steps to perform the above. --- ### OmnichainProposalSender In the contract `OmnichainProposalSender` the role `_owner` has authority over the following functions: - `fallbackWithdraw()` Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and clear a message that was intended to be retried and recover the `msg.value` for themselves. --- In the contract `OmnichainProposalSender` the role `DEFAULT_ADMIN_ROLE` of the `AccessControlManager` can grant addresses the privilege to call the following functions: - `execute()` - `setTrustedRemoteAddress()` - `setConfig()` - `setSendVersion()` - `updateValidChainId()` Any compromise to the `DEFAULT_ADMIN_ROLE` or accounts granted this privilege may allow the hacker to take advantage of this authority and do the following: - Submit a malicious proposal and send it to the remote chain so that it can be executed there. - Change the remote message receiver address to cause a denial of service or to execute malicious functionality. - Change the configuration of the LayerZero messaging library to cause a denial of service. - Update the list of valid chain Id

HighCentralization Related RisksOpen

### BaseXVSProxyOFT In the contract `BaseXVSProxyOFT` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and - Set the oracle to an address that does not provide accurate pricing information. - Pause or unpause the movement of tokens through the contract at critical periods. - Set the max daily limit, the max daily receive limit, the max single transaction limit, and the max single receive transaction limit to values that either are advantageous to the hacker moving funds across chains, or the hacker may set these values to 0 to prevent users from moving funds out of a vulnerable environment. - Set an address they control to be whitelisted and circumvent the bridged amount checks. - Set or remove the trusted remote address, either allowing a malicious remote address or denying service to a trusted remote address. - Remove tokens that correspond to the `outboundAmount` without updating the `outboundAmount`, creating a discrepancy where it appears more tokens are locked in the source bridge than actually are. - Enable or disable the use of `sendAndCall()`. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-a06c-0b3b1e80-b3b7-17acf7c2d335/diagrams/centralization_BaseXVSProxyOFT-BaseXVSProxyOFT-_owner.svg) --- ### XVSBridgeAdmin In the contract `XVSBridgeAdmin` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and make a function signature active within the `functionRegistry` mapping in order to give their account access to this bridge logic through the privilege outlined below. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-92a6-a6cdddc0-a490-c12b73043a96/diagrams/centralization_XVSBridgeAdmin-XVSBridgeAdmin-_owner.svg) In the contract `XVSBridgeAdmin` the role `DEFAULT_ADMIN_ROLE` of the `AccessControlManager` can grant addresses the privilege to call the following functions: - Functions within the XVS Bridge via the `fallback()` function in `XVSBridgeAdmin` - `setTrustedRemoteAddress()` - `transferBridgeOwnership()` Any compromise to the `DEFAULT_ADMIN_ROLE` or accounts granted this privilege may allow the hacker to take advantage of this authority and do the following: - Call privileged functions that the `XVSBridgeAdmin` controls within the XVS Bridge, potentially allowing the hacker to steal funds locked in the bridge or using the bridge minting privilege to steal funds from a pool on one of the bridged chains. - Add a malicious trusted remote contract address in order to take steps to do the above. - Give an account they access the owner privilege of the bridge in order to access other functions so they can take steps to perform the above. --- ### XVSProxyOFTDest In the contract `XVSProxyOFTDest` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and - Remove a failed message from the system so that it cannot be retried. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-92a6-a6cdddc0-a490-c12b73043a96/diagrams/centralization_XVSProxyOFTDest-XVSProxyOFTDest-_owner.svg) --- ### XVSProxyOFTSrc In the contract `XVSProxyOFTSrc` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and - Remove a failed message from the system so that it cannot be retried. - Remove any amount of XVS funds currently held by the contract. - Use the function to inaccurately update the `outboundAmount` through a combination of calls to `sweepToken()` and `fallbackDeposit()`. This may cause a discrepancy where the `outboundAmount` is far larger than the balance the contract actually holds. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-a06c-0b3b1e80-b3b7-17acf7c2d335/diagrams/centralization_XVSProxyOFTSrc-XVSProxyOFTSrc-_owner.svg) --- ### TokenController In the contract `TokenController` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and set the `accessControlManager` to an address they control so that they can make updates via the functions outlined below. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-92a6-a6cdddc0-a490-c12b73043a96/diagrams/centralization_TokenController-TokenController-_owner.svg) In the contract `TokenController`, the role `DEFAULT_ADMIN_ROLE` of the `AccessControlManager` can grant addresses the privilege to call the following functions: - `pause()` - `unpause()` - `updateBlacklist()` - `setMintCap()` - `migrateMinterTokens()` Any compromise to the `DEFAULT_ADMIN_ROLE` or accounts granted this privilege may al

HighCentralized Control of Contract UpgradeOpen

The contract `OmnichainExecutorOwner` is upgradeable; the corresponding `admin` role in each respective proxy has the authority to update the implementation contract behind each contract. Any compromise to the `admin` account in each proxy may allow a hacker to take advantage of this authority and change the implementation contract the proxy points to, and therefore execute potential malicious functionality in the implementation contract.

MediumUnverifiable LogicVenus / Lending Platform · Hacken · 28 Jun 2023Open

The report gives no description here.

Open the report
MediumCheck-Effect-InteractionVenus / DEX · Hacken · 24 Jun 2023Open

The report gives no description here.

Open the report
MediumContradiction - Missing ValidationVenus / Oracle · Hacken · 24 Apr 2023Open

The report gives no description here.

Open the report
MediumContradiction - Missing ValidationVenus / Lending Platform · Hacken · 1 Apr 2023Open

The report gives no description here.

Open the report
Show 10 more
MediumInefficient Gas Model - Uncontrolled IterationsVenus / Lending Platform · Hacken · 1 Apr 2023Open

The report gives no description here.

Open the report
Low`IPrimeV5` Still Relies on Old Solidity VersionMigration Core (Venus) · Quantstamp · 13 Sep 2025Open

`IPrimeV5.sol` still targets Solidity ^0.5.16 and enables the experimental ABIEncoderV2, which is inconsistent with the PR’s goal to standardize on Solidity 0.8.25.

Open the report
LowFallback Function Can No Longer Receive Native TokensMigration Core (Venus) · Quantstamp · 13 Sep 2025Open

Previously, the fallback functions in `Diamond`, `Unitroller`, `VAIUnitroller`, `VBNB`, and `VBep20Delegator` were payable. The pull request changes them to non-payable. As a result, any delegated calls that expect to forward native tokens will now revert.

Open the report
LowMismatched Function Namee-mode Core Pool (Venus) · Quantstamp · 12 Sep 2025Open

The functions `setCollateralFactor()` and `__setCollateralFactor()` are not only involved in setting a market's collateral factor, but also in setting its liquidation threshold. Hence, the function should be named differently, so as to avoid user confusion.

Open the report
LowMissing Or Incomplete NatspecVenus - RiskOracle Integration · CertiK · 19 Feb 2025Open

**RiskStewardReceiver** - `constructor()` and `initialize()` do not have NatSpec comments. - The NatSpec comments for `setRiskParameterConfig()` do not include the `riskSteward` parameter, the event emitted, or the potential errors. - The NatSpec comments for `toggleConfigActive()` do not include the access control, events, or errors. - The NatSpec comments for `processUpdateById()` include the errors `UpdateNotInRange` and `UnsupportedUpdateType`. However, these errors are emitted by the `riskSteward` contract being called and may not always be emitted if new `riskStewards` are utilized. - The NatSpec comments for `processUpdateByParameterAndMarket()` do not include the events or errors. - The functions `_processUpdate()`, `_getMarketUpdateTypeKey()`, and `_validateUpdateStatus()` do not have NatSpec comments. **MarketCapsRiskSteward** - `constructor()` and `initialize()` do not have NatSpec comments. - The NatSpec comments for `setMaxDeltaBps()` do not include the event. - The NatSpec comments for `processUpdate()` do not include the potential events it may emit. - The NatSpec comments for `_updateWithinAllowedRange()` do not include the error. - The functions `_updateSupplyCaps()`, `_updateBorrowCaps()`, `_processSupplyCapUpdate()`, `_processBorrowCapUpdate()`, `_validateSupplyCapUpdate()`, `_validateBorrowCapUpdate()`, and `_decodeBytesToUint256()` are missing NatSpec comments. We assume that all functions should include NatSpec comments. which should include a description of the function, parameters, return values, errors, events, and access control. Please let us know if any if there is another convention you are following in terms of what NatSpec comments will be included for each function. **PolicyFacet** - The NatSpec comments for the function `getBorrowingPower()` do not include the return values. **SetterFacet** - The NatSpec comments for the function `setPrimeToken()` do not include the return value. - The NatSpec comments for the parameter `vTokens` of the function `setMarketSupplyCaps()` reference changing borrow caps, when it should reference changing supply caps. - The functions `__setPriceOracle()`, `__setCloseFactor()`, `__setCollateralFactor()`, `__setLiquidationIncentive()`, `__setMarketBorrowCaps()`, `__setMarketSupplyCaps()`, `__setPrimeToken()`, `__setForcedLiquidation()`, and `__setActionsPaused()` do not have NatSpec comments.

Open the report
LowUnnecessary Cases If Core Comptroller Interface IVenus - RiskOracle Integration · CertiK · 19 Feb 2025Open

If the changes in scope of this audit are made to update the Core Comptroller Interface to be compatible with the Isolated Pools Interface prior to deploying the risk steward contracts, then the `IIsolatedPoolsComptroller` interface can be used for all comptrollers allowing the cited logic to be simplified.

Open the report
LowERC4626 Vaults May Have Decimals Greater Than 18Venus - ERC4626Oracle · CertiK · 6 Feb 2025Open

Some ERC4626 implementations, such as [OpenZeppelin's](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC4626.sol), may have more than 18 decimals. For example, if the OZ implementation is used on an asset that has 18 decimals and the decimal offset is chosen to be 1, then the ERC4626 token will have 19 decimals. (See [here](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/441dc141ac99622de7e535fa75dfc74af939019c/contracts/token/ERC20/extensions/ERC4626.sol#L99C5-L108C6)). There are assumptions made throughout the codebase that the decimals of tokens are less than or equal to 18. If such an ERC4626 token is to be supported, we recommend carefully reviewing to ensure that it does not cause any potential issues within the protocol.

Open the report
LowMissing Input ValidationVenus - ERC4626Oracle · CertiK · 6 Feb 2025Open

The `correlatedToken` is assumed to be an ERC4626 vault, and the input `underlyingToken` must be the asset of the vault. However, it is not checked that the asset of the vault is the input `underlyingToken`. If the incorrect `underlyingToken` is chosen, it will result in an incorrect underlying amount returned and thus will result in inaccurate pricing.

Open the report
LowSupported ERC-4626 Tokens Must Be Compatible WithVenus - ERC4626Oracle · CertiK · 6 Feb 2025Open

The `ERC4626Oracle` contract relies on the security of the underlying ERC-4626 implementation and the behavior of the `convertToAssets()` function. The following specifications should be ensured for every ERC4626 token that is to be supported with this oracle. - It **must** comply with the [ERC-4626](https://eips.ethereum.org/EIPS/eip-4626) specification. - It **should** have been audited and is free from share manipulation vulnerabilities. In particular direct or stealth donation attack vectors should be properly mitigated. - It **should** be non-upgradeable or if it is upgradeable the upgrade authority should be well trusted and carefully monitored. - It **should not** incorporate fees, otherwise, `convertToAssets()` may return an inflated share price as it does not account for the fees charged. - It **should not** incorporate custom logic, such as delayed withdrawals or other constraints that can affect share value. Such mechanisms result in the share value being less than the amount of assets they can be redeemed for due to the delay and available liquidity. Vaults using other custom logic should be considered on a case by case basis to ensure proper integration. - It **should not** include flash loan functionality. If the vault allows flash loans, then during the flash loan the vaults balance will decrease and may manipulate the return value of `convertToAssets()`. - It **should be** highly liquid to ensure negligible slippage when converting shares to assets and vice versa. Otherwise, `convertToAssets()` may be inflated.

Open the report
LowUntitled findingVenus Protocol · Cyberscope · 2 Feb 2025Open

The report gives no description here.

Open the report
Show 10 more
LowUntitled findingVenus Protocol · Cyberscope · 2 Feb 2025Open

The report gives no description here.

Open the report
LowUntitled findingVenus Protocol · Cyberscope · 2 Feb 2025Open

The report gives no description here.

Open the report
LowUntitled findingVenus Protocol · Cyberscope · 2 Feb 2025Open

The report gives no description here.

Open the report
LowUntitled findingVenus Protocol · Cyberscope · 2 Feb 2025Open

The report gives no description here.

Open the report
LowUntitled findingVenus Protocol · Cyberscope · 2 Feb 2025Open

The report gives no description here.

Open the report
LowUntitled findingVenus Protocol · Cyberscope · 2 Feb 2025Open

The report gives no description here.

Open the report
LowUntitled findingVenus Protocol · Cyberscope · 2 Feb 2025Open

The report gives no description here.

Open the report
LowUntitled findingVenus Protocol · Cyberscope · 2 Feb 2025Open

The report gives no description here.

Open the report
LowNo Check That Underlying Token Is Consistent WithVenus - PendleOracle Upgrade · CertiK · 26 Dec 2024Open

The function `_getUnderlyingAmount()` returns the amount of `underlyingToken` for 1 pendle token. If `RATE_KIND = PT_TO_SY`, then it returns the amount of SY for 1 pendle token, so that in this case the `underlyingToken` should be the SY token. Alternatively, if `RATE_KIND = PT_TO_ASSET`, then it returns the amount of underlying asset for 1 pendle token, so that in this case the `underlyingToken` should be underlying asset. However, there are no checks in the `constructor()` ensuring that the correct `underlyingToken` is chosen for the input `rateKind`. If these inputs are not consistent, then the oracle will return an incorrect price.

Open the report
LowDiscussion On Sequence of Granting, Executing, anVenus - ACM Commands Aggregator · CertiK · 7 Oct 2024Open

Venus describes the intended use of this contract with their AccessControlManager as follows: 1. Preload permissions to be granted or revoked in the `AccessControlManager`. 2. Make a VIP on BNB Chain for three commands executed on the corresponding remote network. The three commands are: - Grant the `DEFAULT_ADMIN_ROLE` in the `AccessControlManager` to the `ACMCommandsAggregator`. - Execute functions `executeGrantPermissions()` or `executeRevokePermissions()` with chosen preloaded permission id as needed to grant or revoke the preloaded permissions within the `AccessControlManager`. - Revoke `DEFAULT_ADMIN_ROLE` from the `ACMCommandsAggregator`. The sequence of commands done in step 2 must be performed atomically within the same transaction. Otherwise, the protocol stands the risk of anyone granting or revoking permissions within the `AccessControlManager` within any of the remote chains. This is because all functions within the `ACMCommandsAggregator` are left permissionless. In addition, the permissions associated with the `index` provided must be carefully reviewed prior to the execution of the VIP to ensure that the proper permissions are granted/revoked. In particular, it should be ensured that the `index` is not referencing permissions that were added by unintended entities.

Open the report
Show 10 more
LowInconsistency With Provided DocumentationVenus - Two Kinks Interest Rate · CertiK · 31 Jul 2024Open

The two kink interest rate model gets the borrow rate as a piecewise linear function whose boundary points are given by kink1 and kink2. The provided documentation provided two models, one of which only included linear curves with positive slope, and the second that only allowed for a linear curve with negative slope between kink1 and kink2. However, the implementation makes no checks on any of the multipliers, so that all three linear curves of the piecewise function are allowed to have negative slope. While it may be desired to have negative slope linear curves in the intervals [0, kink1] and [kink1,kink2], the interval [kink2,1e18] has the highest utilization rates and should incentivize users to payback their borrows by having a higher borrow rate. As such the slope for the linear function in this interval should be positive to increase the borrow rates as the utilization rate closely approaches 100 percent. In addition, the utilization of negative multipliers requires the addition of some checks and castings which increase gas costs slightly. As such it may be beneficial to create two separate rate models as in the documentation. One that only allows for positive multipliers and the other which allows for desired negative multipliers. Last, it should be noted that in the case where `max(0, output)` is 0, where `output` represents one of three formulae depending on the subinterval, this may present an extra kink in the interest rate model, via a horizontal slope, until the `output` value is again positive. In this way, there may be more than two kinks in the interest rate model.

Open the report
LowDependency on Choice for `maxAllowedPriceDifferenVenus - sfrxETH oracle adapter · CertiK · 17 May 2024Open

The `maxAllowedPriceDifference` is designed to revert cases when the difference of the two prices returned via the `SfrxEthUsdDualOracle` are greater than it. This helps mitigate issues if one oracle was to be compromised and return the wrong price. However, this value must be chosen high enough that it will not cause a denial of service due to natural discrepancies between the two oracles prices and low enough that it will not allow for a significant manipulated price to be returned.

Open the report
LowInconsistent Use Of `addUint`, `subUint`, `mulUinVenus - VAI Controller Upgrade · CertiK · 26 Apr 2024Open

In the functions `mintVAI()` and `repayVAIFresh()`, the use of functions `addUint`, `subUint`, `mulUint`, and `divUint` was replaced by functions `add_`, `sub_`, `mul_` and `div_` respectively. The main difference is that the previous set of functions returned an error which was either used to revert the transaction and return a specific string message describing where the calculation failed or emit a `Failure` event. The updated version will revert with a generic overflow, underflow, or divide by zero string error. This is done only in the functions `mintVAI()` and `repayVAIFresh()`, with the remaining instances of `addUint`, `subUint`, `mulUint`, and `divUint` in the contract unchanged.

Open the report
LowSend/Receive Limits Can Be Circumvented Via DiffeVenus - Mesh Architecture · CertiK · 19 Apr 2024Open

The mapping `chainIdToMaxDailyLimit[dstChainId_]`, is designed to limit the maximum amount of XVS that can be bridged from the current chain to the chain with `dstChainId_` in a 24 hour period. Similarly, `chainIdToMaxDailyReceiveLimit[srcChainId_]` is designed to limit the maximum amount of XVS that can be bridged to the current chain from the chain with `srcChainId_` in a 24 hour period. However, as there are now multiple paths between bridges, it is possible to bridge more than this amount. As such, this value represents the maximum amount that can be directly bridged, however, the actual amount that can be bridged is the sum of the maximum amounts that can bridged along all paths.

Open the report
LowCopy of Well-Known ContractVenus / Lending Platform · Hacken · 28 Jun 2023Open

The report gives no description here.

Open the report
LowTest CoverageVenus / DEX · Hacken · 24 Jun 2023Open

The report gives no description here.

Open the report
LowConsiderations on Claiming Rewards for Other Users for the VAI and XVS VaultsVenus protocol (vaults) · Quantstamp · 6 Jun 2023Open

The XVS Vault allows anyone to `claim()` a user's interest in any pool. Typically, this is not an issue when the pool has enough rewards to be claimed. However, the XVS vault is limited in its ability to distribute rewards by the number of rewards available in `XVSStore`. If there are not enough rewards at the time the staker claims, they will get fewer rewards than they should. If the rewards are insufficient, stakers would rather wait until they become enough to claim. However, anyone can claim them and force them to lose some part of their rewards. A similar issue exists when claiming the XVS rewards in the VAI vault.

Open the report
LowInaccurate Calculation of Stake Amount for XVS Vault PoolsVenus protocol (vaults) · Quantstamp · 6 Jun 2023Open

According to the code comments, the `getStakeAmount()` function ``` @notice Get the XVS stake balance of an account (excluding the pending withdrawals) ``` However, the returned stake amount only accounts for the pool whose pool and rewards tokens are both XVS. In other words, deposits in pools whose pool token is XVS but the rewards token is not XVS are not considered valid XVS stake balance.

Open the report
LowInaccurate Pending Rewards for VAI Vault UsersVenus protocol (vaults) · Quantstamp · 6 Jun 2023Open

The VAI vault's `pendingXVS()` function may not return the correct amount of XVS rewards the user is eligible for. This function uses `accXVSPerShare` to calculate the rewards, but `accXVSPerShare` is only updated in `updateVault()`. Therefore, the return of `pendingXVS()` is inaccurate between a `updatePendingRewards()` call and the first call that triggers `updateVault()`. Third-party protocols or front-ends calling `pendingXVS()` during this period will get a lower value than the actual.

Open the report
LowMissing Input ValidationVenus protocol (vaults) · Quantstamp · 6 Jun 2023Open

It is important to validate inputs, even if they only come from trusted addresses, to avoid human error. The following functions do not have a proper validation of input parameters: 1. `XVSVault.add()` does not check: 1. that parameters `_rewardToken` and `_token` are different from `address(0)`. 1. that parameters `_rewardPerBlock` and `_lockPeriod` are non-zero. 1. `XVSVault.setXvsStore()` does not check: 1. that parameters `_xvs` and `_xvsStore` are different from `address(0)`. 1. `XVSStore.setPendingAdmin()` does not check: 1. that parameter `_admin` is different from `address(0)`. 1. that parameter `_admin` is different from the previous admin address. 1. `XVSStore.setNewOwner()` does not check: 1. that parameter `_owner` is different from the previous owner address.

Open the report
Show 10 more
LowVaults May Be Insufficiently FundedVenus protocol (vaults) · Quantstamp · 6 Jun 2023Open

All three vaults `VAIVault.sol`, `VRTVault.sol` and `XVSVault.sol` do not guarantee to hold sufficient funds at all times to cash out accrued rewards, as all three do not have automatic funding/minting mechanisms, but rather get funded manually by Venus at certain intervals. In particular reward tokens used in the `XVSVault.sol` and `VAIVault.sol` contracts may pay out until the reward tokens supplies run dry, but will however take in the full deposited value (Due to `XVSStore.safeRewardTransfer()` and `VAIVault.safeXVSTransfer()`, respectively).

Open the report
LowVaults May Not Deliver Full PayoutsVenus protocol (vaults) · Quantstamp · 6 Jun 2023Open

The function `VAIVault.safeXVSTransfer()` transfers whatever XVS it can given the contract's balance, but `VAIVault._withdraw()` and `VAIVault.deposit()` both update the `user.rewardDebt` as if the full payout was delivered. `XVSStore.safeRewardTransfer()` and its usages exhibit the same behavior.

Open the report
LowXVS Vault's Domain Separator Does Not Include a Contract VersionVenus protocol (vaults) · Quantstamp · 6 Jun 2023Open

The domain separator calculated for the XVS vault does not include a `version` field. According to [EIP-712](https://eips.ethereum.org/EIPS/eip-712), > `string version` the current major version of the signing domain. Signatures from different versions are not compatible. Without the `version` field, a signature signed for the current version of the contract can be reused in future versions as long as the current nonce does not change, which can be an issue since the contract may be upgraded again in the future.

Open the report
LowInefficient Gas ModelVenus / Oracle · Hacken · 24 Apr 2023Open

The report gives no description here.

Open the report
LowDivision by ZeroVenus / Lending Platform · Hacken · 1 Apr 2023Open

The report gives no description here.

Open the report
LowIncorrect order of functionsSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The structure of the codebase does not conform to the official Solidity style guide of `v0.5.16` . The style guide can be found at https://docs.soliditylang.org/en/v0.5.16/style-guide.html#orde r-of-functions.

Open the report
LowIncorrect order of functionsSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The structure of the codebase does not conform to the official Solidity style guide of v0.5.16 . The style guide can be found at https://docs.soliditylang.org/en/v0.5.16/style-guide.html#orde r-of-functions.

Open the report
LowInefficient `storage` declarationSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The mapping declarations on the aforementioned lines have `vToken` address as their keys and all of these mapping can be converted into a single mapping where the value will be of struct type. This will greatly reduce the lookup gas costs associated with multiple mappings.

Open the report
LowInefficient `storage` declarationSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The mappings declarations on the aforementioned lines have `user address` as their keys. These mappings can be converted into a single mapping having value of struct type.

Open the report
LowInefficient `storage` layoutSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The properties of struct Market on the aforementioned lines laid out within the struct ineffeciently where they are taking a full 32-bytes in storage in space.

Open the report
Show 10 more
LowInefficient `storage` layoutSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The storage variables on the aforementioned are inefficiently laid out in the storage of the contract.

Open the report
LowInefficient comparisonSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The comparison on the aforementioned line is inefficient as the length of `accountAssets[borrower].length` can never grow beyond maxAssets and hence the comparison can be changed from `accountAssets[borrower].length >= maxAssets` to `accountAssets[borrower].length == maxAssets` which is gas efficient.

Open the report
LowInefficient function declarationsSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The functions on the aforementioned lines perform the same functionalities with one providing public interface while the other one has internal visibility.

Open the report
LowInefficient function implementationSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The function on the aforementioned line loops through holders twice which is inefficient and the code can be rectified to loop through holders only once.

Open the report
LowPossibility of replay attackSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The permit function on the aforementioned line performs the operation of deriving signer address from the signature values of `v` , `r` and `s` . The state varible `DOMAIN_SEPARATOR` that used to calculate hash has a constant value of chainid which does not change after contract deployment. The issue arises in the event of fork when the cross-chain replay attacks can be executed. The attack scenario can be though as if a fork of Ethereum happens and two different networks have id of for example `1` and `9` . The chainid coded in `DOMAIN_SEPARATOR` will be the same on contracts residing in both of the forks. If the chainid is 1 is stored the contract then the permit transaction signed for chainid `1` will be executable on both of the forks.

Open the report
LowRequisite Value of ERC-20 `transferFrom()` / `traSwipe Venus Protocol · CertiK · 16 Dec 2020Open

While the ERC-20 implementation does necessitate that the `transferFrom()` / `transfer()` function returns a `bool` variable yielding `true` , many token implementations do not return anything i.e. Tether (USDT) leading to unexpected halts in code execution.

Open the report
LowUnlocked Compiler VersionSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The contract has unlocked compiler version. An unlocked compiler version in the source code of the contract permits the user to compile it at or above a particular version. This, in turn, leads to differences in the generated bytecode between compilations due to differing compiler version numbers. This can lead to an ambiguity when debugging as compiler specific bugs may occur in the codebase that would be hard to identify over a span of multiple compiler versions rather than a specific one.

Open the report
LowUnlocked Compiler VersionSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The contract has unlocked compiler version. An unlocked compiler version in the source code of the contract permits the user to compile it at or above a particular version. This, in turn, leads to differences in the generated bytecode between compilations due to differing compiler version numbers. This can lead to an ambiguity when debugging as compiler specific bugs may occur in the codebase that would be hard to identify over a span of multiple compiler versions rather than a specific one.

Open the report
LowUnlocked Compiler VersionSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The contract has unlocked compiler version. An unlocked compiler version in the source code of the contract permits the user to compile it at or above a particular version. This, in turn, leads to differences in the generated bytecode between compilations due to differing compiler version numbers. This can lead to an ambiguity when debugging as compiler specific bugs may occur in the codebase that would be hard to identify over a span of multiple compiler versions rather than a specific one.

Open the report
LowUnlocked Compiler VersionSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The contract has unlocked compiler version. An unlocked compiler version in the source code of the contract permits the user to compile it at or above a particular version. This, in turn, leads to differences in the generated bytecode between compilations due to differing compiler version numbers. This can lead to an ambiguity when debugging as compiler specific bugs may occur in the codebase that would be hard to identify over a span of multiple compiler versions rather than a specific one.

Open the report
Show 10 more
LowUnlocked Compiler VersionSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The contract has unlocked compiler version. An unlocked compiler version in the source code of the contract permits the user to compile it at or above a particular version. This, in turn, leads to differences in the generated bytecode between compilations due to differing compiler version numbers. This can lead to an ambiguity when debugging as compiler specific bugs may occur in the codebase that would be hard to identify over a span of multiple compiler versions rather than a specific one.

Open the report
LowUnlocked Compiler VersionSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The contract has unlocked compiler version. An unlocked compiler version in the source code of the contract permits the user to compile it at or above a particular version. This, in turn, leads to differences in the generated bytecode between compilations due to differing compiler version numbers. This can lead to an ambiguity when debugging as compiler specific bugs may occur in the codebase that would be hard to identify over a span of multiple compiler versions rather than a specific one.

Open the report
LowUnnecessary `assert` useSwipe Venus Protocol · CertiK · 16 Dec 2020Open

The `assert` use on the aforementioned line is unnecessary as `i` will always be less than `len` .

Open the report
LowUsage of `uint` instead of `uint256`Swipe Venus Protocol · CertiK · 16 Dec 2020Open

The contract is using `uint` to declare 256-bit unsigned integers. Although, `uint` is an alias for `uint256` and both represent the same underlying integer allocation. It is advisable that for clean coding practices the complete form uint256 should be used instead of the alias `uint` .

Open the report
LowUsage of `uint` instead of `uint256`Swipe Venus Protocol · CertiK · 16 Dec 2020Open

The contract is using uint to declare 256-bit unsigned integers. Although, `uint` is an alias for `uint256` and both represent the same underlying integer allocation. It is advisable that for clean coding practices the complete form `uint256` should be used instead of the alias `uint`.

Open the report
LowUsage of uint instead of uint256Swipe Venus Protocol · CertiK · 16 Dec 2020Open

The contract is using `uint` to declare 256-bit unsigned integers. Although, `uint` is an alias for `uint256` and both represent the same underlying integer allocation. It is advisable that for clean coding practices the complete form `uint256` should be used instead of the alias `uint` .

Open the report
LowUsage of uint instead of uint256Swipe Venus Protocol · CertiK · 16 Dec 2020Open

The contract is using uint to declare 256-bit unsigned integers. Although, uint is an alias for uint256 and both represent the same underlying integer allocation. It is advisable that for clean coding practices the complete form uint256 should be used instead of the alias uint.

Open the report
Low`rewardsDistributors` Array May Contain InactiveOpen

If multiple rewards distributors are allowed for the same token, this may cause the `rewardsDistributors` array to grow excessively large. As the hooks iterate through the entire `rewardsDistributors` array, this may cost a significant amount of gas to be used unnecessarily. In addition, if enough `rewardsDistributors` are added, then this will cause the max loops to need to be adjusted, which may cause issues with other loops that are not dependent on the size of the `rewardsDistributors` array.

Low`whenNotPaused` Could Revert SoonerOpen

The function `_blockingLzReceive()` was overridden to include the `whenNotPaused` modifier. However, if the protocol is paused, then it will cause the transaction to revert without storing the failed message. If it is intended to not store any messages when paused, then the `whenNotPaused` modifier can be moved to an overrided external facing `lzReceive()` function so that it reverts sooner. Alternatively if messages should be stored when paused, then the `whenNotPaused` modifer can be moved to the `_nonblockingLzReceive()` function. However, if this is done a method should be added allowing failed messages to be canceled before unpausing in case malicious failed messages are stored and could be retried. Also we recommend considering adding a method to cancel stored failed messages, because if a malicious proposal is stored as a failed message and then is retried successfully. Canceling each individual transaction could be much more intensive than canceling the failed messages proposal.

LowBlock Time Is Subject to ChangeOpen

The interest rate contracts store an immutable variable `blocksPerYear` to help with calculations. However, the block time for each chain is not guaranteed to remain the same across L2's. For opBNB, the currently configured block time is 1 second, according to the [official document](https://docs.bnbchain.org/opbnb-docs/docs/core-concepts/difference-L2), which, however, includes a warning that it is susceptible to changes.

Show 10 more
LowBlock Time on Polygon zkEVM Depends on Chain UsageOpen

The protocol's interest rate models calculate the borrow and supply rates per block of the markets based on their current utilization rate. The `blocksPerYear` immutable variable in the models is configured based on the deployed chain to adjust the market APR. On Ethereum, BSC, and opBNB chains, the block time can be considered a reliable source of timing information. However, for Polygon zkEVM, the block time is irregular at the time of writing and depends on the chain usage. According to the [historical average block time](https://zkevm.polygonscan.com/chart/blocktime) on the Polygon zkEVM explorer, we can observe that the average block time varies over time and is relatively unreliable. This is because, currently, Polygon zkEVM blocks are produced on-demand, according to [rollup.codes](https://www.rollup.codes/polygon-zkevm), > New L2 blocks contain only one L2 transaction and is created on-demand, i.e., once there is a new transaction. An irregular block time may also affect the reward distribution rate of the XVS vault, which calculates the reward amount based on a configured `rewardTokenAmountsPerBlock` value and the number of passed blocks.

LowChecks-Effects-Interactions Pattern ViolationOpen

If non-reentrant modifiers are used without adhering to the CEI pattern, it cannot guarantee that the global system state is reentrancy-free. There are schemes that can be exploited on a larger scale. All external calls must be executed after the state has been updated because multiple other contracts may depend on the current PegStability contract state. This violation is currently present in `swapStableForVAI()`.

LowMapping `proposalTimelocks` Can Be Optimized As aOpen

If the mapping `proposalTimelocks` is updated to a fixed-length array, deployment cost and the cost to call function `addTimelocks()` will increase slightly, but the calls to functions `execute()` and `cancel()` will decrease in gas cost.

LowMissing Input ValidationOpen

### OmnichainGovernanceExecutor.sol - The constructor is missing a check that `guardian_` is a nonzero address. - The function `addTimelocks()` is missing a check to ensure that each of the entries of `proposalTimelocks` is distinct by the end of all updates. - The function `addTimelocks()` is missing a check to prevent updating to a new timelock while transactions have been queued but not executed or canceled - The function `_nonblockingLzReceive()` is missing a check that all arrays are the same length. - Function `_nonblockingLzReceive()` is missing a check that the `proposalType` decoded in the sent payload is a value between 0 and 2, inclusive. Anything larger will correspond to a `proposalType` that is not implemented. ### OmnichainProposalSender.sol - Function `execute()` is missing a check that all arrays are the same length. - Function `execute()` is missing a check that the `proposalType` decoded in the sent payload is a value between 0 and 2, inclusive. Anything larger will correspond to a `proposalType` that is not implemented.

LowMissing Input ValidationOpen

It is important to validate inputs, even if they only come from trusted addresses, to avoid human error. The following functions are missing validation checks: 1. `ProtocolShareReserve` 1. `initialize()` 1. `_accessControlManager` should not be `address(0)`. 2. `_loopsLimit` should not be `0`. 2. `addOrUpdateDistributionConfigs()` 1. `configs` should have a length greater than `0`. 3. `releaseFunds()` 1. `assets` should have a length greater than `0`. 2. `Isolated Pool VToken` 1. `setReduceReservesBlockDelta()` 1. `_newReduceReservesBlockDelta` should be greater than `0`. Otherwise, this would lead to an inconsistent reduction of reserves. 2. `mint()` 1. Allows to mint based on 0 underlying tokens 3. `Core Pool VToken` 1. `setReduceReservesBlockDelta()` 1. `_newReduceReservesBlockDelta` should be greater than `0`.

LowOracle Assumes a Fixed 1:1 Ratio Between stETH and ETHOpen

The `WstETHOracle` contract returns the price of the `wstETH` token in USD, which is calculated as follows: <p style="text-align: center;">$$P_{WSTETH/USD} = P_{WSTETH/STETH} \times P_{WETH/USD}$$</p> where $$P_{WSTETH/STETH}$$ represents the amount of `stETH` equivalent to 1 `wstETH` token, and $$P_{WETH/USD}$$ represents the price of `WETH` in USD. The former is fetched from the on-chain `stETH` token contract and reflects the actual exchange rate between `wstETH` and `stETH` in the Lido protocol when querying the price. The latter is fetched and returned from the `ResilientOracle`. This pricing formula assumes a 1:1 ratio between `stETH` and `ETH`, i.e., `stETH` is pegged to `ETH`. Such a design raises the following security concerns: 1. The oracle is unable to reflect the market price of `stETH`. Suppose `stETH` depegs from `ETH`, which may be due to reasons such as a large amount of `ETH` being removed from the Curve `stETH/ETH` pool. The market price of `stETH` has dropped, while the protocol may overvalue `stETH` temporarily during the depeg event. Assuming the depeg does not recover in time (note that withdrawals from Lido are not confirmed instantly compared to deposits), positions with `wstETH` as collateral will have an advantage in terms of borrowing power during this period. 1. Suppose the depeg continues so that the spread between the exchange rate and the market price is larger than $$1 - LT$$ (where $$LT$$ represents the liquidation threshold). In that case, it will become profitable to deposit `stETH` as collateral to the protocol, borrow `ETH`, and sell it in the secondary market. The utilization rate of `ETH` may increase, leading to potential issues such as lacking liquidity for withdrawals. 1. In an extreme scenario where the depeg cannot be recovered, the protocol may accrue bad debts if underwater positions with `wstETH` as collateral cannot be liquidated in time.

LowOutdated Solidity VersionOpen

As security standards develop, so does the Solidity language. In order to stay up to date with current practices, it's important to use a recent version of Solidity and recent conventions.

LowPotential DoS Issue in `ProtocolShareReserve`'s `addOrUpdateDistributionConfigs()`Open

The `ProtocolShareReserve.addOrUpdateDistributionConfigs()` function allows privileged roles to add or update the distribution configurations. Before these configurations are updated, the `_accrueAndReleaseFundsToPrime()` function is invoked to signal `Prime` to accrue interests. Then, `ProtocolShareReserve` transfers funds to `Prime` by invoking the `_releaseFund()` internal function with every asset in the `Prime` contract's market as an argument. According to the code comments, the accrual and release of funds to `Prime` are necessary before updating the distribution configurations. However, this design introduces a potential issue where failing to accrue and release funds to `Prime` will block the configuration updates. Additionally, during the `_releaseFund()` function call, two external calls occur: 1. Tokens are transferred from `ProtocolShareReserve` to each configured destination. 2. The `updateAssetsState()` function is called on each destination contract. If any of the external calls fails, the entire transaction fails. Failures can occur due to various reasons, including but not limited to: 1. A bug in the `Prime` contract causing the interest accrual call to fail. 2. A bug on the destination contracts causing the `updateAssetsState()` call to fail. 3. Token transfer failures to the destination contracts, which can occur due to token pausing, reverting on zero-value transfers, blacklisting of the sender or receiver, etc. In cases 1 or 2, the `Prime` or destination contracts may require fixes and/or upgrades to unblock the `addOrUpdateDistributionConfigs()` call. In case 3, a potential solution could be the `Prime` contract removing the problematic tokens from its market. However, regardless of the specific issue, the problematic configuration can block the updates of others until the issue is resolved.

LowPrivileged Roles and OwnershipOpen

Smart contracts often have operations that can only be executed by a limited amount of addresses with special privileges. The access control mechanism of the current contract is enforced using the contract `AccessControlledV8` and the function `_checkAccessAllowed()`. The contract `PegStability.sol` gives the following privileges: 1. Any authorized address can pause (function `pause()`) and unpause (function `resume()`) the contract. Swaps are only possible when the contract is not paused. 2. Any authorized address can update the storage variables: * `feeIn` and `feeOut` within the range `0` to `9999`, which means a fee of `0%` to `99.99%`; * `vaiMintCap` which represents the maximum amount of VAI that can be minted by this contract; * `venusTreasury` which represents the beneficiary address of swap fees; * `oracle` which represents the address giving the current price of the stable token in USD. Note that the access control mechanism is currently managed via governance decisions.

LowUncapped Fee RangeOpen

The only bounds included for the `feeIn` or `feeOut` are that they do not meet or exceed 100%. This means the fees can be assigned high values such as 99%, which would result in a poor user experience.

Show 2 more
LowUntitled findingOpen

The report gives no description here.

LowUpgradabilityOpen

While upgradability is not a vulnerability in itself, users should be aware that the `PegStability` implementation contract can be upgraded. This audit does not guarantee the behavior of future implementation contracts that `PegStability` may be upgraded to. Here are two examples of what could contain a malicious upgraded contract: - A function draining all stable tokens owned by the contract to an arbitrary address. - A function minting any amount of VAI (because the proxy address is authorized to mint VAI).

Incidents2

Attached through a shared contract address. Our incident data ends in Oct 2026.

Incident

Incident,

5M.

Source: De.Fi incident database.

Audits before it
4.
Audits since
63, the latest dated 13 Sep 2025.
Incident

Incident,

Source: De.Fi incident database.

Audits before it
1.
Audits since
66, the latest dated 13 Sep 2025.

Contracts2

AddressChainSource code
0xd3cc9d8f3689b83c91b7b59cab4946b063eb894aChain: EthereumSource code: Verified source
0x67c549a18abfad127b13f8d56738f43a21bb62a7Chain: BNB ChainSource code: Verified source

All 2 addresses and the files the reports name

Show this on your site

Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.

Content

Facts

Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.

Fixed as
Language

Style

Layout
Theme
Accent
Corners

Format

Size
Date
Embed as
HTML
<head>
<script src="https://widget.trustblock.run/project-widget.min.js" defer></script>
</head>
<body>
<div
data-tb-project-widget
data-tb-project-slug="venus-protocol"
></div>
</body>

Paste the code where the label should appear. It uses no API credit and updates by itself.

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us