Volatility Technologies Ltd

QuantstampFiles named in the report

Quantstamp reviewed Volatility Technologies Ltd on 22 Nov 2023: 13 findings, 0 critical; 7 marked fixed, 6 open.

No open critical findings
Open the reportOpen Volatility Technologies Ltd’s security record

Report hosted on certificate.quantstamp.com.

Trustblock does not review code.

Findings13

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

SeverityOpenAcknowledgedFixed
Critical000
High000
Medium000
Low607
LowPotential Integer Overflow Can Break System's AccountingOpen

There are various locations where integer overflow can occur in the codebase, which can lead to inaccurate rewards accounting and unintentional reverts. In particular, we have the following snippet from `_resolveLot()`: ```solidity! if (startPriceTokenA == 0 || d2 > d1) { lot.totalClaimPoolB = (2 * (size - feeAmountPerSide)).toUint128(); winningToken = lot.tokenB; } // If token B is invalid or if token A had a greater increase in price... else if (startPriceTokenB == 0 || d1 > d2) { lot.totalClaimPoolA = (2 * (size - feeAmountPerSide)).toUint128(); winningToken = lot.tokenA; } // Otherwise, in the case of a tie... else { uint128 claim = (size - feeAmountPerSide).toUint128(); lot.totalClaimPoolA = claim; lot.totalClaimPoolB = claim; } ``` It is possible for `(2 * (size - feeAmountPerSide))` to be greater than `2^128`. In which case, casting it back to the `uint128` will lead to an inaccurate accounting of how much the users can claim. This happens when `size` is on the order of `2^128`. However, this is unlikely to happen because `size` equals how many collateral tokens are in the lot, and per discussion with the team, these tokens will likely be stablecoins. Furthermore, it is also possible for the following snippet in `_resolveLot()` to revert: ```solidity! if (!priceFeed.isInvalid(lot.tokenA)) { startPriceTokenA = priceFeed.getHistoricalPrice(lot.tokenA, lot.startTimestamp); resolvePriceTokenA = priceFeed.getHistoricalPrice(lot.tokenA, endTimestamp); } if (!priceFeed.isInvalid(lot.tokenB)) { startPriceTokenB = priceFeed.getHistoricalPrice(lot.tokenB, lot.startTimestamp); resolvePriceTokenB = priceFeed.getHistoricalPrice(lot.tokenB, endTimestamp); } uint256 d1 = resolvePriceTokenA * startPriceTokenB; uint256 d2 = resolvePriceTokenB * startPriceTokenA; ``` Since `priceFeed.getHistoricalPrice()` returns a type of `uint256`, it is possible to overflow in the calculation of `d1` and `d2`, causing unintentional reverts. The likelihood of this happening depends on the results of the price feed and how the Relative Finance team chooses to represent the price in the price feed backend.

LowPrivileged Roles and OwnershipOpen

Smart contracts will often have `owner` variables to designate the person with special privileges to make modifications to the smart contract. We list the areas where owners have special privileges and the corresponding actions they can take. 1. `owner`: 1. `MultiLot.setIsValidCollateralToken()` 2. `MultiLot.setPriceFeed()` 3. `MultiLot.withdrawFee()` 4. `MultiLot.setFeePercentage()` 5. `MultiLot.pauseContract()` 6. `MultiLot.unpauseContract()` 2. `ORACLE_ROLE` 1. `PriceFeed.store()` 2. `PriceFeed.setInvalid()` 3. `DEFAULT_ADMIN_ROLE` 1. Any role-related modifications in `AccessControl`, inherited by `PriceFeed`.

LowSame Tokens May Be Represented by Different StringsOpen

The `price` mapping maps token strings to timestamp slots that contain the token prices at a given time. The mapping doesn't differentiate between strings like `ETH` and `eth`, allowing for the possibility of having two different prices for the same token.

LowSystem Heavily Depends on Off-Chain ComponentsOpen

The correctness of the whole system depends on the data correctness from the price feed, which is maintained by the Relative Finance team off-chain. In particular, the rewards accounting will be most impacted by inaccurate data from the price feed. Furthermore, if, at any point in time, price data is not submitted to the price feed contract (due to benign or malicious reasons), any lot that depends on the price at that timeslot will revert upon calling `_resolveLot()`, which means users will not be able to withdraw their funds from the system. The availability and correctness of the price feed are critical to the health and functionality of the system. While the off-chain part is not in the scope of this audit, we simply want to raise awareness of the reliance on off-chain components and their associated risks.

LowUser Cannot Withdraw if Token Price Drops to ZeroOpen

A "lot" in general supports betting across arbitrary asset classes, as long as the token is supported by the price feed. However, an asset (e.g. NFT) can potentially have a price of `0 ETH` (e.g. starts from `0 ETH` or drops to `0 ETH`). The current code will then revert whenever `PriceFeed.getHistoricalPrice()` is called, which means it will revert whenever a user tries to resolve the lot.

LowUser Has to Pay Fees Even for Tokens Unsupported by the Price FeedOpen

Currently, there are no checks for whether the tokens involved in a "lot" are supported by the price feed. If a user creates a "lot" with invalid tokens (e.g. the tokens `_tokenA` and `_tokenBChoices` passed as parameters to `createLot()` are not supported by the price feed), then, while the players can still withdraw their funds, they will lose a portion of their funds to the fees collected in `_resolveLot()`.

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 (3)

  • src/IPriceFeed.sol
  • src/PriceFeed.sol
  • src/MultiLot.sol

Part of Volatility Technologies Ltd’s security record

Volatility Technologies Ltd
Audits1 audit by 1 firmLast audit Nov 2023, by Quantstamp.
Critical findingsNo open critical findingsIn 1 report.
Open Volatility Technologies Ltd’s security record

Security firm

Quantstamp

236 projects reviewed · 332 reports · latest Oct 2026

See Quantstamp’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