Vmex Finance’s 2nd audit competition has officially ended! Hats off to the incredible security researchers who continue to make the Web3 space safe.
The VMEX team has set a new benchmark in the domain of pre-launch audits. This final report provides a comprehensive summary of all legitimate submissions and the associated payouts from the team. Collaborating with Certore on formal verification during this competition further strengthened our endeavor.
Our first audit spanned from 19th June to 3rd July, followed by a second audit session from 24th July to 30th July.
We offer our utmost respect to the exemplary security researchers contributing their expertise to ensure the safety and security of the Web3 ecosystem. This article aims to provide an insightful walkthrough of the exhaustive process behind each audit competition, emphasizing the importance of transparent dialogue between projects and security professionals.
About the competition
The competition started on June 19th and ended on July 3rd. VMEX contracts were initially audited by yAuditDAO. We received over 50 submissions, out of which 12 were valid.
2 high severities
8 low severities
- 1st place: 0xB…4Ad
- 2nd place: 0xD…1A4
Title: Incorrect access control in IncentivesController.handleAction()
The researcher revealed a flaw in the way the ExternalRewardDistributor stores stakingData, which allowed any malicious party to steal funds from the IncentivesController contract by impersonating an aToken. VMEX fixed this issue by changing the accounting such that only the original aTokens of the protocol can enter into the protected functions. Since this resulted in a loss of funds, it was awarded a high severity.
Title: Velodrome LP Share calculation wont work for all velodrome pools #24
The researcher found that the fair reserves formula used in VMEX’s Velodrome oracle (although works for volatile pairs) was not applicable to stable pairs due to its different invariant. This allowed any party to manipulate the reserves of the pair, causing the price to be artificially inflated, and allowing a borrow position to be quickly opened and drain the protocol. Although the borrow caps and supply caps should limit the damage, we still awarded this a high severity as funds can be lost.
Title: Liquidations will be frozen when the chainlink oracle goes offline
The researcher argued that Chainlink’s price fetching should be encased in a try-catch block in order to prevent reverts from freezing liquidations. This issue was disputed by VMEX and the researcher and was decided to be low severity since we found that Chainlink’s getLatestRound should not revert per the docs. However, since in previous communication, we already assigned it a low rating, we have still awarded the researcher.
Title: Some tokens cannot be added as Reward
The researcher found that approve was used instead of safeApprove, which prevented certain rewards from being added to the protocol. Since this did not lead to loss of funds or any significant DoS, but still deviated from expected behavior, we assigned it a low rating
Title: Any whitelisted account can break the protocol by blocking setAssetAllowed()
The researcher found that an out of gas (OOG) error is possible if around 700 tranches have been created, thus blocking setAssetAllowed() setting an asset to disallowed. This is because setting an asset to be disallowed requires a loop through all tranches to make sure there is no liquidity in any tranche. The researcher claimed that this would be a DoS on the essential functionality of asset deprecation. However, since global admins can change the LTV and liquidation threshold without such looping through all tranches (in fact, this is our preferred method of depreciating assets), and since there is no better solution, we awarded this a low severity.
Title: VMEX would overvalue collateral if if the token’s USD price feed’s decimals != 8
The researcher noted that if the decimals returned by Chainlink’s price feeds are inconsistent, it could lead to hugely inconsistent accounting and loss of funds. However, on optimism, there is no such Chainlink USD price oracle with decimals other than 8, and the assets we are supporting do not have such issues. Thus, we awarded it a low severity, as it is a good practice but no funds are at risk.
Title: claim all rewards function fails to accrue rewards correctly
The researcher found that the claimAllRewards function doesn’t call _batchUpdate, so some state is not updated when users call claimAllRewards. The only stale values are the lastUpdateTimestamp, but there are no vulnerabilities that can be exploited if that value is stale. Regardless, the value gets fixed if users call claimReward(), and all the rewards still end up going to the right users. Thus, we awarded this a low severity since it was not intended behavior but there are no funds at risk.
Title: Reward calculation is incorrect
The researcher found that configureRewards() allowed the permissioned EMISSION_MANAGER to add multiple copies of the same reward to the _allRewards array. The researcher noted that there was not a critical vulnerability where rewards could be claimed multiple times, since when a reward is claimed it updates the state of accruedRewards to 0. Since there were no funds at risk, only an overpaying of gas, and unintentional behavior, we have accepted this as a low severity issue.
Title: Curve Reentrancy Guard will not work if the pool implements a fallback
The researcher found that the curve read-only reentrancy guard fails if the curve pool defines a fallback function since the guard will pass even if the function doesn’t exist. However, because of the specific pools we support, the vulnerability doesn’t present itself on those pools, so we marked it as a low severity as no funds are at risk now.
Title: Duplicate errors messages
Errors.sol contains duplicate values for different errors, causing confusion.
We introduced a new category: “Formal Verification.” Under this segment, researchers had the privilege to use the Certora Prover to identify bugs and prove specific properties of the codebase. Some predefined contracts were already set up for this purpose. The most outstanding specifications crafted for these contracts stood a chance to win from the severity prize pool.
The results for the “Formal Verification” category are as follows:
1- successfully identified 35 bugs.
2- trailed close behind with 23 detected bugs.
3- spotted 22 bugs.
Each of these remarkable winners was awarded $2250 in USDC. Congratulations to them!
2nd competition winners
- 0x9…B41 (2 findings)
- 0xb…3d1 + bonus
Title: Claim of AURA rewards can be griefed by claiming for the contract (low severity)
The researcher noted that claiming Aura rewards can be done by anyone on behalf of the IncentivesController, meaning that the rewards could be claimed but no tracked event would be emitted, causing the off-chain External Rewards Distributor to misaccount the funds. Rewards could still be manually adjusted to the correct addresses, so no funds are at risk, so we accepted this as a low-severity issue.
Title: Balancer Oracle stable pairs need to divide by the rate
The researcher found that the logic for calculating the price of stable balancer pools did not consider the rate of the oracle. This means that in cases where the on-chain exchange rate deviates from the market price (if say Rocket Pool experiences an exploit in which their underlying ETH is drained), the balancer oracle would report an inaccurate price. Since the probability of such an attack is low, this issue is marked as low severity.
Title: Verified tranche admins can steal staked liquidity from all tranches
The researcher found that verified tranche admins could create their own custom aToken contracts that are outside the LendingPool, and redirect funds to their aToken contract, thus rugging liquidity of the protocol. Since verified tranche admins are assumed to be trusted actors in the protocol, this issue was accepted as low severity.
Title: Some stable velo pool oracles destabilize with massive swaps
The researcher found that the USDC/USDT velodrome pool LP token price can be manipulated to up to 2 or 3 times the expected value with massive swaps due to the value of K changing due to rounding errors of the nonstandard decimals. However, the amount of liquidity needed to perform such deviations is over 50 billion, which is not feasible to do on optimism. However, since the pool could lose liquidity over time (decreasing the amount of liquidity needed to perform the attack), the researcher’s finding is valid low severity as it informs VMEX that the USDC/USDT pool should not be supported.
Final Remarks from the Vmex Protocol Team
Working with the Hats Finance team to launch our first-ever audit competition was a wonderful and seamless experience. Their team’s responsiveness paired with their easy-to-use on-chain procedures made the audit competition a great success. So much so that we are launching a second audit competition with Hats!
Final Remarks from the Hats
Working with Vmex has given us fresh ideas. Thanks to this, we’re making our product even better and ready for more checks after audits. We’re also working on tools that will help groups get more from our product. Keep an eye out for cool updates!
Both audit competitions went well. In the first one, Vmex was able to find 2 high vulnerabilities missed in the audit they ran before the audit competition. In the second competition, they made sure the problems were fixed properly.
Big thanks to the Vmex team! They care about making sure everything’s safe and work hard for their users.
Stay updated on the next audit competition sign up to our wallet-to-wallet notifications.