Venom Bridge

CertiKFiles named in the report

CertiK reviewed Venombridge (Venom Bridge) on 3 Nov 2022: 33 findings, 0 critical; 19 marked fixed, 5 acknowledged, 9 open.

No open critical findings
Open the reportOpen Venombridge’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings33

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

SeverityOpenAcknowledgedFixed
Critical000
High052
Medium006
Low9011
HighMiscalculation of `debtRatio` in Function `updateFixed

```solidity=768 /** @notice Change the quantity of assets `strategy` may manage. This may be called by `governance` or `management`. @param strategyId The Strategy to update. @param _debtRatio The quantity of assets `strategy` may now manage. */ function updateStrategyDebtRatio( address strategyId, uint256 _debtRatio ) external override onlyGovernanceOrManagement strategyExists(strategyId) { StrategyParams memory strategy = _strategy(strategyId); _debtRatioReduce(strategy.debtRatio); _strategyDebtRatioUpdate(strategyId, _debtRatio); _debtRatioIncrease(debtRatio); require(debtRatio <= MAX_BPS); emit StrategyUpdateDebtRatio(strategyId, _debtRatio); } ``` Function `updateStrategyDebtRatio()` is supposed to updates `debtRatio` (the total quantity of assets that all strategies can manage) by reducing `strategy.debtRatio` and increasing `_debtRatio`. However, the function call of `_debtRatioIncrease()` at line 787 mistakenly uses `debtRatio` as the parameter rather than `_debtRatio`, which would cause the value of `debtRatio` to be higher than the actual ratio that all strategies can manage. Since `debtRatio` cannot exceed 100% and the total ratio that all strategies can manage is smaller than `debtRatio`, the strategies cannot take full advantage of the assets in the vault contract.

HighUpgradeable Contracts Extend Non-Upgradeable ContFixed

Upgradeable contract must extend upgradeable contracts and call initializer functions of parent-contracts in its own initializer function. Otherwise, it may malfunction due to improper initialization or improper upgrading.

MediumFunction `updateStrategyPerformanceFee()` UpdatesFixed

```solidity=830 function updateStrategyPerformanceFee( address strategyId, uint256 _performanceFee ) external override onlyGovernance strategyExists(strategyId) { require(_performanceFee <= MAX_BPS / 2); performanceFee = _performanceFee; emit StrategyUpdatePerformanceFee(strategyId, _performanceFee); } ``` Function `updateStrategyPerformanceFee()` updates the global variable `performanceFee` rather than `strategies_[strategyId].performanceFee`.

MediumImplementation Contract Is Not Initialized AutomaFixed

When developers deploy the implementation contract and call the function `initialize()` from the Proxy contract, the initialization will be executed in the context of the Proxy contract. Hence the state variable `_initialized` and `_initializing` will be 0 and false, respectively. However, the "initialize" function in the implementation contract is not initialized, and attackers can directly call the function `initialize(),` with malicious inputs to take over the implementation contract. Reference: https://medium.com/immunefi/wormhole-uninitialized-proxy-bugfix-review-90250c41a43a https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#initializing_the_implementation_contract

MediumIncorrect interface usedFixed

Based on code L72 in the `MultiVaultEverscaleEventAlien.sol` contract, `IProxyMultiVaultAlien_V3` should be used instead of `IProxyMultiVaultAlien_V1` at L140.

MediumLack of Storage GapFixed

For upgradeable contracts, there must be a storage gap to "allow developers to freely add new state variables in the future without compromising the storage compatibility with existing deployments". Otherwise, it may be very difficult to write new implementation code. Without a storage gap, the variable in the child contract might be overwritten by the upgraded base contract if new variables are introduced to the base contract. Refer to https://docs.openzeppelin.com/contracts/3.x/upgradeable#storage_gaps

MediumMissing ModifiersFixed

Function `Vault.deposit()` at line 374 misses modifiers `onlyEmergencyDisabled` and `respectDepositLimit`, function `Vault.saveWithdraw()` at line 489 misses modifier `nonReentrant`, and function `MultiVault.deposit()` at line 623 misses modifier `onlyEmergencyDisabled`,

MediumNo Access Control and modifier on `forceWithdraw(Fixed

```solidity=1169 /** @notice Force user's pending withdraw. Works only if Vault has enough tokens on its balance. This may only be called by wrapper. @param pendingWithdrawalId Pending withdrawal ID */ function forceWithdraw( PendingWithdrawalId memory pendingWithdrawalId ) public override onlyEmergencyDisabled pendingWithdrawalOpened(pendingWithdrawalId) pendingWithdrawalApproved(pendingWithdrawalId) { PendingWithdrawalParams memory pendingWithdrawal = _pendingWithdrawal(pendingWithdrawalId); IERC20(token).safeTransfer(pendingWithdrawalId.recipient, pendingWithdrawal.amount); _pendingWithdrawalAmountReduce(pendingWithdrawalId, pendingWithdrawal.amount); emit PendingWithdrawalForce(pendingWithdrawalId.recipient, pendingWithdrawalId.id); } ``` `Vault.forceWithdraw()`'s comment says that the function may only be called by "wrapper", however, the role does not exist and anyone can call the function to withdraw a pending withdrawal to its recipient. `MultiVault.forceWithdraw()` shares the same issue, and it also misses modifiers like `nonReentrant` and `onlyEmergencyDisabled`.

Low`mergePoolVersion` not included in upgrade dataFixed

`mergePoolVersion` is not included in upgrade data. Its value will be lost after the upgrade. Reference: https://docs.everscale.network/develop/smart-contract/learn/how-to-upgrade-contracts https://github.com/tonlabs/samples/blob/master/solidity/12_BadContract.sol and https://github.com/tonlabs/samples/blob/master/solidity/12_NewVersion.sol

LowCheck-Effect-Interaction Pattern ViolationFixed

```solidity modifier withdrawalNotSeenBefore(bytes memory payload) { bytes32 withdrawalId = keccak256(payload); require(!withdrawalIds[withdrawalId], "Vault: withdraw payload already seen"); _; withdrawalIds[withdrawalId] = true; } ``` The value of `withdrawalIds[withdrawalId]` is updated after `_;` runs, which violates the check-effect-interaction pattern.

Show 9 more
LowInconsistency in Fee CalculationFixed

In contract `Vault`, the fee calculation uses `amountPlusBounty`; whereas in contract `MultiVault`, the fee calculation uses `amount` rather than `amountPlusBounty`.

LowInconsistency in Function `blacklistAddToken()`Fixed

```solidity=260 /// @notice Add token to blacklist. Only native token can be blacklisted. /// Blacklisted tokens cant be deposited or withdrawn. /// @param token Token address function blacklistAddToken( address token ) public override onlyGovernance tokenNotBlacklisted(token) { tokens_[token].blacklisted = true; emit BlacklistTokenAdded(token); } ``` Function `blacklistAddToken()`'s comment says that this function should only backlist "native" tokens; however, the function could also blacklist alien tokens and stop them from being deposited or withdrawn since no check guarantees the token is "native".

LowInconsistency in Function `setWithdrawalQueue()`Fixed

```solidity=300 /// @notice Changes `withdrawalQueue` /// This may only be called by `governance` function setWithdrawalQueue( address[20] memory queue ) external override onlyGovernanceOrManagement { withdrawalQueue_ = queue; emit UpdateWithdrawalQueue(withdrawalQueue_); } ``` The comment says "This may only be called by `governance`", however, the modifier `onlyGovernanceOrManagement` allows both `governance` and `management` to call this function.

LowMissing Check For `bounty`Fixed

Function `saveWithdrawAlien()` at line 727 does not require that `pendingWithdrawal.bounty` <= `pendingWithdrawal.amount`. If `pendingWithdrawal.bounty` > `pendingWithdrawal.amount`, this `pendingWithdrawal` will not be filled until `pendingWithdrawal.bounty` is modified.

LowMissing Event EmitFixed

There should always be events emitted in the sensitive functions that are controlled by privileged roles.

LowMissing Input ValidationFixed

The given input `vault` is missing the check for the non-zero address.

Lowredundant code logicFixed

The identified code logic at L144-146 in BaseEvent.sol is redundant: only when the current status is initializing, `status` can be set to initializing.

LowState variable `owner` not included in upgrade daFixed

State variable `owner` is not included in upgrade data. So after the upgrade, its value will be lost. Reference: https://docs.everscale.network/develop/smart-contract/learn/how-to-upgrade-contracts https://github.com/tonlabs/samples/blob/master/solidity/12_BadContract.sol and https://github.com/tonlabs/samples/blob/master/solidity/12_NewVersion.sol

LowUnused ModifierFixed

Both the "onlyInitializer" and "eventInitializing" modifiers usage is not found in the bridge codebase.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (133)

  • everscale/contracts/bridge/alien-token/AlienTokenWalletPlatform.sol
  • everscale/contracts/bridge/interfaces/IProxyExtended.sol
  • everscale/contracts/utils/cell-encoder/CellEncoderStandalone.sol
  • ethereum/contracts/bridge/Bridge.sol
  • ethereum/contracts/multivault/interfaces/IMultiVault.sol
  • everscale/contracts/utils/cell-encoder/ProxyTokenTransferCellEncoder.sol
  • everscale/contracts/staking/UserData.sol
  • everscale/contracts/dao/structures/ActionStructure.sol
  • everscale/contracts/dao/interfaces/IVoter.sol
  • everscale/contracts/staking/base/StakingRelay.sol
  • everscale/contracts/bridge/interfaces/multivault/IMultiVaultEverscaleEventAlien.sol
  • everscale/contracts/bridge/proxy/alien/ProxyMultiVaultAlien_V3.sol
  • everscale/contracts/bridge/interfaces/event-configuration-contracts/IEverscaleEventConfiguration.sol
  • everscale/contracts/bridge/interfaces/alien-token-merge/IMergeRouter.sol
  • everscale/contracts/staking/interfaces/IRelayRound.sol
  • everscale/contracts/staking/interfaces/ITokensReceivedCallback.sol
  • ethereum/contracts/multivault/interfaces/IERC20.sol
  • everscale/contracts/bridge/interfaces/multivault/IMultiVaultEverscaleEventNative.sol
  • ethereum/contracts/Registry.sol
  • ethereum/contracts/vault/Vault.sol
  • everscale/contracts/staking/Staking.sol
  • everscale/contracts/bridge/alien-token/TokenRootAlienEVM.sol
  • everscale/contracts/bridge/factory/ProxyTokenTransferFactory.sol
  • everscale/contracts/bridge/event-contracts/base/EthereumBaseEvent.sol
  • everscale/contracts/staking/StakingV1_1.sol
  • everscale/contracts/bridge/event-contracts/base/EverscaleBaseEvent.sol
  • everscale/contracts/utils/cell-encoder/ProxyMultiVaultCellEncoder.sol
  • ethereum/contracts/DAO.sol
  • everscale/contracts/dao/DaoRoot.sol
  • everscale/contracts/utils/Receiver.sol
  • everscale/contracts/bridge/alien-token-merge/MergePool.sol
  • everscale/contracts/bridge/interfaces/event-contracts/IEverscaleEvent.sol
  • ethereum/contracts/multivault/utils/ChainId.sol
  • everscale/contracts/staking/RelayRound.sol
  • everscale/contracts/bridge/interfaces/legacy/ILegacyTransferOwner.sol
  • everscale/contracts/bridge/event-contracts/base/BaseEvent.sol
  • ethereum/contracts/multivault/utils/Initializable.sol
  • ethereum/contracts/multivault/MultiVaultToken.sol
  • everscale/contracts/bridge/event-contracts/token-transfer/TokenTransferEverscaleEvent.sol
  • everscale/contracts/bridge/event-configuration-contracts/EverscaleEventConfiguration.sol
  • everscale/contracts/bridge/interfaces/event-contracts/IBasicEvent.sol
  • everscale/contracts/bridge/interfaces/IConnector.sol
  • everscale/contracts/bridge/interfaces/multivault/IProxyMultiVaultAlien_V1.sol
  • everscale/contracts/staking/libraries/Gas.sol
  • everscale/contracts/dao/structures/PlatformTypes.sol
  • everscale/contracts/staking/base/StakingBase.sol
  • everscale/contracts/dao/interfaces/IProposal.sol
  • ethereum/contracts/vault/VaultHelpers.sol
  • everscale/contracts/bridge/interfaces/multivault/IMultiVaultEVMEventNative.sol
  • everscale/contracts/utils/cell-encoder/MergePoolCellEncoder.sol
  • ethereum/contracts/multivault/utils/Context.sol
  • ethereum/contracts/bridge/BridgeMockup.sol
  • everscale/contracts/bridge/interfaces/ITokenRootAlienEVM.sol
  • everscale/contracts/bridge/event-contracts/multivault/MultiVaultEVMEventAlien.sol
  • everscale/contracts/bridge/alien-token-merge/MergeRouter.sol
  • everscale/contracts/bridge/alien-token-merge/MergePoolPlatform.sol
  • ethereum/contracts/multivault/interfaces/proxy/IBeacon.sol
  • everscale/contracts/dao/libraries/DaoErrors.sol
  • ethereum/contracts/vault/VaultStorage.sol
  • everscale/contracts/utils/ErrorCodes.sol
  • everscale/contracts/bridge/event-contracts/staking/StakingEthEvent.sol
  • ethereum/contracts/multivault/proxy/Proxy.sol
  • everscale/contracts/staking/StakingRootDeployer.sol
  • everscale/contracts/staking/interfaces/IUpgradableByRequest.sol
  • everscale/contracts/utils/cell-encoder/DaoCellEncoder.sol
  • ethereum/contracts/multivault/utils/Ownable.sol
  • everscale/contracts/bridge/interfaces/alien-token-merge/IMergePool.sol
  • everscale/contracts/utils/Delegate.sol
  • everscale/contracts/bridge/interfaces/IProxy.sol
  • everscale/contracts/utils/TransferUtils.sol
  • ethereum/contracts/multivault/MultiVault.sol
  • everscale/contracts/dao/structures/ProposalSates.sol
  • everscale/contracts/bridge/event-contracts/token-transfer/TokenTransferEthereumEvent.sol
  • everscale/contracts/bridge/interfaces/event-contracts/IEthereumEvent.sol
  • ethereum/contracts/bridge/StakingRelayVerifier.sol
  • everscale/contracts/bridge/interfaces/IProxyTokenTransferConfigurable.sol
  • everscale/contracts/dao/structures/ProposalConfigurationStructure.sol
  • ethereum/contracts/multivault/interfaces/IMultiVaultToken.sol
  • ethereum/contracts/utils/ReentrancyGuard.sol
  • everscale/contracts/staking/Encoder.sol
  • everscale/contracts/staking/Election.sol
  • everscale/contracts/bridge/interfaces/IStaking.sol
  • ethereum/contracts/multivault/utils/ReentrancyGuard.sol
  • ethereum/contracts/utils/Initializable.sol
  • everscale/contracts/bridge/interfaces/multivault/IProxyMultiVaultNative.sol
  • ethereum/contracts/multivault/proxy/TransparentUpgradeableProxy.sol
  • everscale/contracts/bridge/interfaces/multivault/IMultiVaultEVMEventAlien.sol
  • everscale/contracts/staking/interfaces/IElection.sol
  • ethereum/contracts/multivault/interfaces/IEverscale.sol
  • everscale/contracts/staking/base/StakingUpgradable.sol
  • everscale/contracts/dao/interfaces/IStakingAccount.sol
  • everscale/contracts/bridge/Bridge.sol
  • everscale/contracts/bridge/interfaces/event-configuration-contracts/IEthereumEventConfiguration.sol
  • everscale/contracts/bridge/Connector.sol
  • ethereum/contracts/utils/Token.sol
  • everscale/contracts/bridge/interfaces/IRound.sol
  • ethereum/contracts/multivault/interfaces/IBridge.sol
  • ethereum/contracts/multivault/proxy/ProxyAdmin.sol
  • ethereum/contracts/multivault/interfaces/IERC20Metadata.sol
  • everscale/contracts/bridge/interfaces/IBridge.sol
  • everscale/contracts/bridge/interfaces/IEventNotificationReceiver.sol
  • everscale/contracts/bridge/factory/EverscaleEventConfigurationFactory.sol
  • everscale/contracts/bridge/factory/EthereumEventConfigurationFactory.sol
  • everscale/contracts/bridge/event-contracts/multivault/MultiVaultEVMEventNative.sol
  • everscale/contracts/staking/interfaces/IStakingPool.sol
  • ethereum/contracts/utils/Cache.sol
  • everscale/contracts/dao/interfaces/IUpgradableByRequest.sol
  • ethereum/contracts/multivault/proxy/ERC1967Proxy.sol
  • everscale/contracts/dao/Proposal.sol
  • ethereum/contracts/multivault/proxy/ERC1967Upgrade.sol
  • everscale/contracts/dao/libraries/Gas.sol
  • everscale/contracts/staking/libraries/PlatformTypes.sol
  • everscale/contracts/bridge/event-contracts/dao/DaoEthereumActionEvent.sol
  • everscale/contracts/staking/interfaces/IStakingDao.sol
  • everscale/contracts/bridge/alien-token/AlienTokenWalletUpgradeable.sol
  • everscale/contracts/bridge/interfaces/legacy/ILegacyBurnTokensCallback.sol
  • everscale/contracts/bridge/interfaces/event-configuration-contracts/IBasicEventConfiguration.sol
  • everscale/contracts/utils/cell-encoder/StakingCellEncoder.sol
  • everscale/contracts/utils/Platform.sol
  • everscale/contracts/dao/interfaces/IDaoRoot.sol
  • everscale/contracts/bridge/event-contracts/multivault/MultiVaultEverscaleEventAlien.sol
  • everscale/contracts/bridge/event-contracts/staking/StakingTonEvent.sol
  • everscale/contracts/utils/cell-encoder/TokenCellEncoder.sol
  • everscale/contracts/bridge/event-contracts/multivault/MultiVaultEverscaleEventNative.sol
  • everscale/contracts/staking/interfaces/IUserData.sol
  • everscale/contracts/bridge/proxy/ProxyTokenTransfer.sol
  • ethereum/contracts/multivault/interfaces/proxy/draft-IERC1822.sol
  • ethereum/contracts/utils/ChainId.sol
  • everscale/contracts/dao/interfaces/IUpgradable.sol
  • everscale/contracts/bridge/interfaces/multivault/IProxyMultiVaultAlien_V3.sol
  • everscale/contracts/dao/interfaces/IProposer.sol
  • everscale/contracts/bridge/proxy/ProxyMultiVaultNative.sol
  • everscale/contracts/bridge/event-configuration-contracts/EthereumEventConfiguration.sol

Part of Venombridge’s security record

Venombridge
Audits1 audit by 1 firmLast audit Nov 2022, by CertiK.
Critical findingsNo open critical findingsIn 1 report.
Open Venombridge’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’s audits

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