Guardian's review of Pyth Updates for GMX, published July 2024. The report records 14 findings, including 8 medium and 6 low.
- Published
- Review window
- July 19 to 22, 2024
- Language
- Solidity
- Chains
- Arbitrum, Avalanche
- Sector
- Perpetuals
- 0 Critical
- 0 High
- 8 Medium
- 6 Low
- 0 Informational
Findings 14
-
M-01 Medium Staleness Validation Inaccuracy Logical Error Acknowledged
Description
In the
_setPricesWithDatafunction the_setLastUpdatedValuescall assigns the latest block details as the last update which is used to determine the staleness of a price.However the Pyth price can be from up to 60 seconds before the current block, based on Pyths default configured staleness check. Therefore the
maxPriceUpdateDelayandpriceDurationvalidations will be off by up to 60 seconds.Recommendation
Consider adjusting the
lastUpdatedAtto keep track of the publish time for each token’s price from Pyth. Otherwise adjust themaxPriceUpdateDelayandpriceDurationto account for this potential 60 second lag time. -
M-02 Medium Pyth Confidence Intervals Are Not Considered Logical Error Acknowledged
Description
Pyth prices offer a confidence interval range for every price, this is because the exact price of an asset cannot be given due to difference across exchanges and reporting sources.
Pyth recommends that the confidence interval be used in two ways, which could be adapted to the use-case for the FastPriceFeed contract:
- Opt to not use the Pyth price if the confidence range becomes too wide, as this is an indication of uncertain pricing which may lead to profitable arbitrage opportunities.
- Apply the confidence range returned from Pyth as a spread, moving in the direction that would be disadvantageous for traders.
Recommendation
Consider adopting one or both of these use-cases for the pyth confidence interval to provide protection for uncertain pricing results.
-
M-03 Medium Deviation Truncation Prevents Spread Logical Error Acknowledged
Description
In the
getPricefunction, the diffBasisPoints are calculated with round down precision loss which leads to hasSpread reporting false when the deviation has in fact exceeded the maximum allowable amount.For example:
- maxDeviationBasisPoints = 100
- BTC reference price: 64,338
- BTC fastPrice: 64,987
- diffBasisPoints = 64,987 - 64,338 * 10000 / 64,338 = 100.873511766, truncated to 100
- The fastPrice is considered to be within the maxDeviation because a strict greater than comparison is used
As a result prices which are above the maxDeviationBasisPoints can be flagged as within the deviation range and will not have a spread applied.
Recommendation
Use a >= comparison rather than a strict > comparison for the maxDeviationBasisPoints check.
-
M-04 Medium Pyth Prices Are Used Even When Disabled Logical Error Acknowledged
Description
In the
getPricefunction a spread is used if the fastPrice is deemed to be unsatisfactory. In the event that the favorFastPrice function returns false a spread is applied where the fastPrice can be used if it is the worse price for traders.However if the fastPrice has been flagged by watchers to be inaccurate or even malicious it should not be used in any capacity for the resulting price, even if this value is not desirable for traders.
Recommendation
Consider handling the disableFastPriceVoteCount spread separately, where the spread does not include the fastPrice. Additionally consider if the maxCumulativeDeltaDiffs spread should use the fastPrice as well.
-
M-05 Medium Experimental Pragma Usage Warning Acknowledged
Description
The
FastPriceFeedcontract now utilizes the experimentalABIEncoderV2to support thebytes[] calldataparameter for the_setPricesWithDatafunction. There are several known bugs pertaining to theABIEncoderV2in Solidity0.6.12.Specifically,
AbiReencodingHeadOverflowWithStaticArrayCleanupandABIDecodeTwoDimensionalArrayMemorydocumented at https://docs.soliditylang.org/en/v0.8.25/bugs.html affect Solidity version0.6.12.Neither of these issues affect the
FastPriceFeedcontract currently, however future changes to this contract may introduce unexpected vulnerable behavior due to these known issues.Additionally, there may be further undocumented or undiscovered bugs affecting the
ABIEncoderV2with Solidity version0.6.12which could affect the contracts in their present form.Recommendation
Be aware of these known bugs when making future changes to the and consider upgrading to an up to date version of Solidity, where known
ABIEncoderV2bugs have been addressed. -
M-06 Medium Spread Taken Multiple Times Logical Error Acknowledged
Description
The FastPriceFeed's
getPricefunction is called by the VaultPriceFeed'sgetPriceV2function. In multiple cases,getPricemay return a price with a spread applied ontop of it. However, thegetPriceV2will apply another_spreadBasisPointsonto the returned price. Consequently, two spreads are applied on the price, exacerbating the impact on user's orders.Furthermore, if
VaultPriceFeed:getPriceis called, it will trigger functiongetPriceV2and then apply one more spread —adjustmentBasisPoints. Three spreads are applied to a single price.Recommendation
Do not apply another spread in the VaultPriceFeed. Otherwise, if intended, clearly document this behavior.
-
M-07 Medium Cumulative Delta Does Not Get Compounded Logical Error Acknowledged
Description
Sequential percent changes cannot be added to see the overall, cumulative price movement. Two 10% price movements is not 20% but 21%.
Consequently, the
cumulativeRefDeltais less than the true move, leading to potentially not favoring the fast price, inaccurate event emission, and systems that rely on that data.Recommendation
To get the true measure of price movement, multiply the percent changes.
-
M-08 Medium block.number used on Arbitrum Logical Error Acknowledged
Description
Using
block.numberon Arbitrum returns the L1 Mainnet block close to when the sequencer received the transaction. This may unnecessarily prevent updates with the revert "FastPriceFeed: minBlockInterval not yet passed".Recommendation
On Arbitrum, utilize ArbSys to fetch the Arbitrum block number.
-
L-01 Low Unused Code Optimization Acknowledged
Description
In the FastPriceFeed contract the BITMASK_32 variable is unused.
Recommendation
Remove the BITMASK_32 variable.
-
L-02 Low Full Price Duration Range Cannot Be Used Logical Error Acknowledged
Description
In the
_setPricesWithDatafunction thepythPrice.publishTimevalidation uses a strict greater than comparison with theblock.timestamp - _priceDurationto determine if a price is stale.However because a strict greater than is used the full
_priceDurationis not available for prices retrieved from pyth.Recommendation
Consider using a
>=comparison to allow the final second in the fresh range to be used. -
L-03 Low Misnamed Parameters Documentation Acknowledged
Description
In the
PositionRouterInterface the first parameter for theexecuteIncreasePositionsfunction is defined as the_count, however in the implementation for theexecuteIncreasePositionsfunction this parameter is named_endIndex.Recommendation
Consider standardizing on one parameter name across the interface and function implementation.
-
L-04 Low Lacking Configuration Validations Documentation Acknowledged
Description
In the
FastPriceFeedcontract there are lacking validations for the trusted setter functions, therefore if trusted addresses are compromised they can assign values which would cause stale prices or even DoS the exchange.For instance, if the
maxPriceUpdateDelayis assigned to 0 and thespreadBasisPointsIfChainErroris assigned to the maxuint256, calls to thegetPricefunction will revert and DoS all interactions with the GMX vault.Recommendation
Consider adding validations that the values assigned in the trusted setter functions are within an expected range.
-
L-05 Low Lack of maxPriceUpdateDelay Validation Warning Acknowledged
Description
The
lastUpdatedAtcan only be updated everyminBlockInterval. IfmaxPriceUpdateDelayis less than time passes within theminBlockInterval, functiongetPricewill always return the price withspreadBasisPointsIfChainErroradded.Recommendation
Ensure
maxPriceUpdateDelayis larger than the time passed within theminBlockInterval. -
L-06 Low Array Length Mismatch Warning Acknowledged
Description
The length of
_tokensis not validated against the length of_maxCumulativeDeltaDiffsinsetMaxCumulativeDeltaDiffs.This may lead to unintended consequences such as a token being set with the wrong max delta diff.
Recommendation
Consider validating that the two arrays are the same length.
No findings match.
More from GMX
All 44 reportsPut your code through the same review.
This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.
