Guardian's review of TLX for Synthetix, published December 2024. The report records 39 findings across 2 review rounds, including 3 high and 13 medium.
- Published
- Review window
- December 3 to 12, 2024
- Rounds
- Main Review, Remediation Review
- Language
- Solidity
- Chains
- Ethereum, Optimism, Base, Arbitrum
- Sector
- Perpetuals
- 0 Critical
- 3 High
- 13 Medium
- 23 Low
- 0 Informational
Scope
14 files in scope · 1,833 nSLOC
| File | nSLOC | Lines |
|---|---|---|
src/ZapSwap.sol | 171 | 251 |
src/TlxUpkeepRegistry.sol | 51 | 72 |
src/RebalanceUpkeepSetupManager.sol | 101 | 122 |
src/PythPriceHandler.sol | 44 | 59 |
src/ProxyOwner.sol | 100 | 132 |
src/ParameterProvider.sol | 101 | 147 |
src/LeveragedTokenProxy.sol | 12 | 18 |
src/LeveragedTokenFactory.sol | 192 | 244 |
src/LeveragedToken.sol | 445 | 587 |
src/AddressProvider.sol | 136 | 205 |
src/upkeeps/RebalanceUpkeep.sol | 99 | 125 |
src/upkeeps/LinkTopupUpkeep.sol | 148 | 183 |
src/upkeeps/FundUpkeep.sol | 194 | 242 |
src/upkeeps/BaseUpkeep.sol | 39 | 57 |
Findings 39
Main Review
34 findings · December 3 to 7, 2024-
H-01 High Rebalance Extractable Value Sandwhich Attack Partially resolved
Description
In the
_submitLeverageUpdatefunction theacceptablePricevalue is determined by applying a standard slippage amount to the result of thefillPricefunction.However the result of the
fillPricefunction itself can be manipulated such that it returns a higherfillPriceand thus allows for significant extractable value by sandwiching the TLX vault’s order.Consider the following scenario:
- A malicious actor observes that a significant amount of PnL has built up for the TLX vault and that a rebalance will be triggered by even a small deposit.
- The malicious actor creates a large long order to push the skew of the market higher.
- The malicious actor triggers a small deposit with the
mintForfunction, triggering a rebalance. - The rebalance order is assigned a high
acceptablePricewhich can be significantly more than the fair market value of the index asset due to the inflated price impact. - The malicious actor subsequently closes their position directly after the rebalance order is executed, receiving positive impact at the expense of the leveraged token vault holders.
Recommendation
Consider basing the acceptable price off of an independent oracle which cannot be manipulated on-chain.
-
H-02 High Slippage Amounts Charged Are Lost Logical Error Resolved
Description
In the
redeemForfunction thebaseAmountReceivedwhich is sent to the user is reduced by theslippageamount, however the fullbaseWithdrawnamount which is removed from the margin in Perps V3 includes this slippage amount.Therefore the slippage amount of sUSD will sit in the
LeveragedTokencontract and will now not be tracked as value in the system since thetotalValueresult is entirely dependent on the result ofperpsMarket.getAvailableMargin.Explicitly, the accounting which occurs on redemption is as follows.
Removed from SNX and credited to the LeveragedToken contract:
baseWithdrawn
Debited from the
LeveragedTokencontract and sent elsewhere:baseAmountReceived = baseWithdrawn - fee - slippagefee
Thus it is clear to see that
baseWithdrawnis received andbaseAmountReceived + fee = baseWithdrawn - fee - slippage + fee = baseWithdrawn - slippageis sent out. This results inslippageamount of sUSD being left in the contract.Recommendation
Deduct
slippagefrombaseWithdrawnafter computing the slippage. Notice that this will charge thefeePercenton the amount which will be withdrawn and sent to the user instead of the amount to be withdrawn plus the slippage. We believe this behavior to be correct, but the protocol should independently verify this. -
M-01 Medium Operations DoS When Minimum Credit Is Invalidated DoS Acknowledged
Description
In the
_validateMintAmountfunction the mint amount is validated to be within the maximum open interest for the relevant side and market. However the Perps market as a whole is not validated to be within theminimumCreditconstraint.The deposited funds may put the Perps market over the allowed open interest based on the current credit capacity delegated to it by the V3 core system. This results in a DoS of all deposit/withdrawal actions as they attempt to commit orders which will revert due to the minimum credit validation here: https://github.com/Synthetixio/synthetix-v3/blob/306c928de0da52d6e839f0620f8f32d544217648/markets/perps-market/contracts/storage/AsyncOrder.sol#L371
Recommendation
Include the minimum credit validation with an appropriate buffer in the
_validateMintAmountfunction. -
M-02 Medium Stale hasPendingLeverageUpdate Validation Resolved
Description
The
hasPendingLeverageUpdatefunction relies upon thesizeDeltaof the stored order in the Perps V3 system, however stale orders which will be automatically overwritten upon a new order commitment still exist in the order storage.Therefore stale orders are considered a pending leverage update even though they are inactive. In the case that a stale order is left for the system this will prevent rebalances during this period of time.
Recommendation
Consider checking if the current timestamp is within the
settlementStrategy.settlementDelay + settlementStrategy.settlementWindowDurationof the order commitment, if it is not then the order is stale and should not be considered pending. -
M-03 Medium Deposits Allowed While Liquidatable Unexpected Behavior Resolved
Description
In the
mintForfunction there is no validation that deposits cannot occur while the leveraged token’s Perps V3 position is in a liquidatable state. If a rebalance is triggered by the deposit then the validation in the SNXvalidateRequestfunction will prevent such an action. However if the deposit is not large enough, or if the deposit corrects for a high leverage caused by losses and thus puts the leverage back in range and does not trigger a rebalance then the deposit will be allowed while the position is liquidatable.Users who deposit in this case will experience an immediate loss of funds as there is no way to withdraw their assets due to the liquidation checks and the position will be subsequently liquidated.
Recommendation
Consider validating that the position is not in a liquidatable state in the
_validateMintAmountfunction. Notice that being in a liquidatable state is not the same as checking if the position is flagged for liquidation, theLiquidationModule.canLiquidatefunction should be used for a complete validation. -
M-04 Medium Depositors May Be Trapped Due To Pending PnL Unexpected Behavior Acknowledged
Description
In Synthetix V3 pending profits cannot be immediately withdrawn from the system until an order has been made to settle those profits to the account margin.
This behavior means that the TLX system may be illiquid for users to withdraw from until a rebalance occurs. In the past TLX has recommended a recursive approach for withdrawals to trigger a rebalance so that the pending PnL can be settled to margin in order to withdraw.
However there are certain edge cases that this approach would miss. The clearest example is if the Perps V3 position is in a state where there is 0 margin and all pending profit. In this case no withdrawal can be triggered to induce a rebalance and unlock all of the pending PnL as liquidity for withdrawers.
This scenario can be achieved if smaller withdrawals are made which stay within the deviation range and these withdrawals are subsequently corrected for in the PnL changes.
Recommendation
This is a rare edge case and may never present itself in production. Nevertheless it may be helpful to include a trusted function to settle outstanding PnL by submitting a dummy order to the Perps V3 system so that users can get liquidity to withdraw.
-
M-05 Medium Decaying Redemption Fee Manipulation Gaming Acknowledged
Description
In the leveraged token system a decaying redemption fee is applied to users who have recently deposited. Throughout the codebase the decaying redemption fee is assigned to start off at a 25% fee and decay to 0% over the course of 25 minutes.
The minimum deposit for a user which will reset the timer for the decaying redemption fee is set as 1e18 or 1 USD in the
Configcontract as theDECAYING_REDEMPTION_MIN_BASE_AMOUNTvalue.With these configured parameters it can be significantly profitable for one vault depositor to do a small deposit on behalf of another depositor who is about to withdraw and cause them to experience a significant decay fee. The malicious vault depositor in this case would gain from the significant fee paid by the victim depositor in this case.
On networks without a public mempool specifically frontrunning a user’s withdrawal transaction is not reliably possible so this attack may operate based upon key indicators that a user is about to withdraw such as Discord messages or market volatility.
Furthermore, if the
DECAYING_REDEMPTION_MIN_BASE_AMOUNTis configured too high, then a depositor could simply depositDECAYING_REDEMPTION_MIN_BASE_AMOUNT- 1 wei multiple times to avoid the decaying redemption fee while still depositing a large amount. This could occur in a single transaction with a multicall or for-loop contract call around themintForfunction.Recommendation
As a first option, consider requiring that a user has approved another user to
mintForon their behalf.Alternatively, configure the
DECAYING_REDEMPTION_MIN_BASE_AMOUNT,decayingRedemptionFeeStart, anddecayingRedemptionFeeDurationwith these behaviors in mind. Ensuring that theDECAYING_REDEMPTION_MIN_BASE_AMOUNTis neither too low to incentivize bad faith mints on behalf of other users and that theDECAYING_REDEMPTION_MIN_BASE_AMOUNTvalue is not too high to incentivize split deposits to avoid the decay fee measure. -
M-06 Medium Redeployed Token Lost From Token Mappings Logical Error Resolved
Description
Function
redeployInactiveTokencallsdelete _tokens[marketId][targetLeverage][isLong]which deletes the newly deployed token rather than the old, inactive token. ConsequentlytokenExistswill produce an incorrect result and leveraged tokens can be created even for active markets withcreateLeveragedTokenssinceif (tokenExists(marketId, targetLeverage, true)passes.Recommendation
Do not clear the mapping, since it is set to the new token upon redeploy.
-
M-07 Medium Outdated Price Used For Rebalances Validation Acknowledged
Description
The
rebalancefunction does not include any validation against the oracle price staleness with the_ensureOraclePriceLivelinessfunction, nor does it offer a way for the upkeep caller to update the pyth price.Therefore stale prices may be used on accident or on purpose which will incorrectly compute the
sizeDeltafor the leverage update of the system. This will ultimately perturb the leverage of the vault system after a rebalance because the price used to determine thesizeDeltacan be in some cases on the order of days old.Recommendation
Include a
_ensureOraclePriceLivelinessvalidation in therebalancefunction as well as a pathway to update the oracle price with the_updateOraclePricefunction. -
M-08 Medium Missing Referral Accrediting Logical Error Acknowledged
Description
In the
_chargeRedemptionFeefunction if areferralCodeis provided thebaseAssetis transferred to thereferralsaddress, however there is no logic to accredit the referral fee amount to the referrer who owns thereferralCode.Recommendation
Implement the necessary logic to accredit the referrer who owns the
referralCode. -
M-09 Medium Lacking Mint Referral Unexpected Behavior Acknowledged
Description
The
mintForfunction accepts areferralCodeparameter, however no referral fee is charged. Currently thereferralCodeis only emitted in theMintedevent.Recommendation
Implement the referral fee logic for the
mintForfunction, otherwise remove thereferralCodeparameter. -
M-10 Medium Stale Price Arbitrage Gaming Acknowledged
Description
In the
LeveragedTokencontract the pyth feed used to determine the value of the system position is required to be updated with a price in the last 60 seconds of the action being performed.In times of volatility this can present an arbitrage opportunity whereby a price from 60 seconds ago is abused to make a net positive deposit/withdrawal pair from the vault.
Consider the following scenario:
- The leveraged token vault is long
- Price increases by 1% for the index asset of the vault in the last 60 seconds, from $100 to $101
- User A has an existing deposit of 10 tokens in the vault
- User A makes a deposit for 10 tokens with a new address and provides pyth update data for 60 seconds ago, when the price is $100
- Directly after this User A makes a withdrawal for their original 10 token address and provides the latest Pyth data of $101
User A has now arbitraged the difference between the $100 price and $101 price. Having withdrawn at $101 and deposited the same amount at $100.
Recommendation
Consider reducing the staleness period allowed for the Pyth feed. Furthermore, consider adding an additional fee that is charged to the user upon deposit/withdrawal to reduce the feasibility of this attack.
-
M-11 Medium Order Fees Do Not Include Settlement Costs Logical Error Acknowledged
Description
In the
_orderFeefunction the order fee computed does not include the settlement costs which are levied based on thesettlementRewardCostin the Perps V3 system.This is a one time hard cost that will be applied to every rebalance that occurs and is not specifically remunerated by the depositors/withdrawers who are triggering the rebalance.
Recommendation
Consider if this is acceptable. If it is not, consider requiring that the actor who triggers the rebalance covers the fee for the settlement cost.
-
M-12 Medium Max Market Size Unchecked Logical Error Resolved
Description
The Perps market
validatePositionSizevalidation validates both the max market size and max market value, however the TLX_validateMintAmountvalidation only validates the max market value.It is possible that the max value validation is not reached but the max size validation is reached, thus allowing a mint to occur in the TLX vault when the corresponding order cannot go through causing a DoS for actions that would trigger a rebalance.
Recommendation
Consider adding validation for the market size in addition to the existing value validation.
-
L-01 Low Storage Compatibility Best Practices Acknowledged
Description
The TlxOwnableUpgradeable contract is intended to be compatible with upgradeable contracts, but it does not use namespaced storage.
This can create issues with future upgrades if the storage layout were to change as documented here: https://eips.ethereum.org/EIPS/eip-7201.
Recommendation
Consider using namespaced storage in the
TlxOwnableUpgradeablecontract. -
L-02 Low Unexpectedly Large Redemption Fee Unexpected Behavior Acknowledged
Description
In the
redeemForfunction the redemption fee is multiplied by the target leverage to determine the fee amount levied on the redeemer. The redemption fee percentage is currently configured as 0.5% in theConfigcontract, therefore if the leveraged token vault is using a target leverage of 10x the redemption fee can be as high as 5%.This value seems quite high for a redemption fee and may be unexpected by the protocol.
Recommendation
Confirm whether the redemption fee ought to be multiplied by the target leverage, effectively making it a proxy for a notional value fee. If the redemption fee is not meant to reach 5% of the redeemers deposited funds then consider removing the leverage multiplication.
-
L-03 Low Price Impact Charged Successively Unexpected Behavior Acknowledged
Description
In the
computePriceImpactfunction the price impact for each deposit/withdrawal is computed regardless of if it triggers a rebalance. Furthermore the price impact charged to the user is not concerning the individual contribution the user made to the order size, but instead the entire price impact experienced by the wholerebalanceSizeDelta.Consider the following scenario in which the
rebalanceSizeDeltawhich will correspond to a rebalance is 100 index tokens.rebalanceSizeDeltais initially 0- Leverage is 2x for example
- 1 sUSD == 1 index token
- User A deposits 20 sUSD and is charged impact for a
rebalanceSizeDeltaof 40 - User A deposits 20 more sUSD and is charged impact for a
rebalanceSizeDeltaof 80 - User A deposits 20 more sUSD and is charged impact for a
rebalanceSizeDeltaof 120 - The
rebalanceSizeDeltais now greater than 100 and thus an order is triggered. The vault pays impact for an order size of 120. However user A has paid impact fees for each of 40, 80, and 120 sizeDelta orders.
Recommendation
Consider if this behavior is acceptable. If it is not then consider one of the following solutions.
Firstly, the price impact on the
rebalanceSizeDeltacan only be levied as a fee to the user ifcanRebalanceis true and the rebalance order will be submitted.Alternatively, the price impact charged to the user can be the difference in price impact experienced between the pre-existing
rebalanceSizeDeltawhich results from the marginBalance without their deposit/withdrawal and the newrebalanceSizeDeltawhich includes their deposit/withdrawal. In other words, the price impact that is charged to the user is exactly the price impact difference that their action induces. Notice that these two solutions should not be combined. -
L-04 Low Unnecessary Return Value Optimization Resolved
Description
The
computePriceImpactfunction returns a boolean as it’s second return value, however this value is always assigned as true.Recommendation
Consider removing the boolean from the return values of the
computePriceImpactfunction or implement it’s use-case. -
L-05 Low Small Actions Prevented By Price Impact Warning Acknowledged
Description
When performing a deposit or withdrawal action the price impact that would be experienced by the entire rebalance order is levied against the user. In some cases where there is a large pending rebalance and the deposit or withdrawal is relatively small this may result in an underflow revert when deducting the slippage from the amount to be deposited or withdrawn.
Recommendation
Consider if this is acceptable behavior. If it is then be sure to document it for users and consider introducing a more descriptive custom error and validation for this case.
-
L-06 Low Max Leverage Inaccuracy Warning Acknowledged
Description
The
_maxLeveragefunction computes the maximum allowable leverage as1/minimumInitialMarginRatioD18_however in the Perps V3 system the maximum allowed leverage for the initial margin validation is based onminimumInitialMarginRatioD18 + initialMarginRatioD18 * impactOnSkew.By this logic the max leverage should be
1/(minimumInitialMarginRatioD18 + initialMarginRatioD18 * impactOnSkew)where theimpactOnSkewis based on the upper bound of leveraged token vault size.In the following case we can examine how much the maximum leverage calculation would be off for the ETH market:
skewScale = 1_000_000e18initialMarginRatioD18 = 1160000000000000000 (1.16)minimumInitialMarginRatioD18 = 20000000000000000 (0.02)- Max expected vault size: 2,000 ETH
maximum leverage = 1 / (minimumInitialMarginRatioD18 + initialMarginRatioD18 * impactOnSkew) = 1 / (0.02e18 + 1.16e18 * 2_000e18/1_000_000e18) = 44.8028673835x max leverageHowever the existing calculation computes the maximum leverage as
1 / minimumInitialMarginRatioD18 = 1e18 / 0.02e18 = 50x max leverageRecommendation
The max leverage which is used to validate the initial leverage is simply divided by 2 to give a rough validation so that the target leverage allows some buffer between the maximum allowable initial margin, so some inaccuracy may be acceptable here.
If the level of inaccuracy demonstrated is not acceptable, then consider adopting the more exact max leverage calculation which incorporates the
initialMarginRatioD18andimpactOnSkew. -
L-07 Low Lacking safeTransfer Best Practices Resolved
Description
In the
ZapSwapmint functiontransferFromis used on an arbitraryzapAssetwithout checking the return value.Recommendation
To be compatible with all tokens use
safeTransferFromin case any token which does not revert on failure is supported. -
L-08 Low Lacking Expo Validation Validation Resolved
Description
In the PythPriceHandler contract there is no validation to ensure that the
pythPrice.expois indeed a negative number.Currently there are no feeds which have this characteristic, however out an abundance of caution if any feeds were to be supported with a positive expo or if any feeds were to be misconfigured the application should revert instead of providing a significantly incorrect price result.
Recommendation
Consider adding a validation against a positive
pythPrice.expovalue in thegetLatestPricefunction. -
L-09 Low Lacking resetFailedCounter Function Warning Resolved
Description
The
FundUpkeepcontract does not include aresetFailedCounterfunction which is seen in theRebalanceUpkeepcontract. This function may be useful if any unexpected issues were to occur and the failed counter needed to be reset.Recommendation
Consider adding a
resetFailedCounterto theFundUpkeepcontract in case of any unexpected scenarios where the failed counter should be reset. -
L-10 Low Superfluous LinkTopupUpkeep Instances Unexpected Behavior Resolved
Description
The
setupRebalanceUpkeepfunction configures a newlinkTopupUpkeepfor every new marketId which is configured. ThecheckDatafor this upkeep is the marketId, however thecheckUpkeepfunction for theLinkTopupUpkeepcontract does not make use of this upkeep check data.Every instance of the
LinkTopupUpkeepupkeep will check all upkeep contracts registered in the upkeep registry for upkeeps, therefore there is no need to configure aLinkTopupUpkeepfor every market id.Recommendation
Only configure the
LinkTopupUpkeeponce as this single instance can cover all upkeep contracts. -
L-11 Low Incorrect Interface Return Value Logical Error Resolved
Description
In the
linkTopupUpkeepfunction the returned value uses theIFundUpkeepinterface, however this is not the interface of thelinkTopupUpkeepcontract.Recommendation
Correct the return value type to the
ILinkTopupUpkeepinterface and consider if there should be a function in theAddressProviderto retrieve theFundUpkeepcontract instance. -
L-12 Low FundUpkeep Failure Due To Large Amounts Unexpected Behavior Acknowledged
Description
In the
FundUpkeepcontract the upkeep action attempts to balance the remaining margin value of the leveraged token at thetargetAmountPerTokenwhen the amount goes out of the minimum or maximum ranges.However in the case where the deposits in a
LeveragedTokenvault become too large it may be impossible for the FundUpkeep contract to redeem to meet thetargetAmountPerTokenas it does not have enough leveraged tokens to do so. This will result in consistent failures for the upkeep action as the redeem action will continue to revert with an ERC20 balance underflow.The same could occur for a mint upkeep action though is less likely as there is a lower bound of value which can be in the vault.
Recommendation
Be aware of this behavior and consider limiting the minted/redeemed amount to the balance of the
FundUpkeepcontract in these cases. -
L-13 Low Base Amount Griefing Warning Acknowledged
Description
Because ZapSwap simply uses the entire balance of
baseAssetwithin the contract to mint leveraged tokens, a malicious user can donatebaseAssettokens directly to the contract, and potentially triggerMaxMarketValueExceededin the mint which would prevent users from utilizing the zap functionality.Recommendation
Either use the amount of bases assets obtained from the swap or clearly document this behavior.
-
L-14 Low Arbitrary Address Warning Warning Acknowledged
Description
The
zapAssetAddressis an arbitrary address passed by the user which may lead to an unsafe, external contract taking control of execution.Recommendation
It is generally best practice to avoid arbitrary addresses. Consider validation on the
zapAssetAddressor document this behavior. -
L-15 Low Hardcoded Positions Warning Resolved
Description
_validateOdosSwapAllDatauses bytes 28 and 8 depending on whether the address is encoded or not to ensure the entire balance is being swapped. This works forswapCompactbut notswapMultiCompactwhich loops through multiple inputs.Recommendation
Clearly document this behavior.
-
L-16 Low Users May Avoid Streaming Fee Gaming Acknowledged
Description
Users may observe that a significant streaming fee has accrued over time and choose to withdraw their deposits to avoid the streaming fee. So long as a user does not withdraw enough funds to trigger a rebalance, they will successfully avoid the streaming fee.
Recommendation
Be aware of this minor gaming of the streaming fee. Know that the amount that can be avoided is limited to what the deviation factor will allow to go without rebalance. However if a solution is desired then the streaming fee can be levied on all deposits and withdrawals.
-
L-17 Low Streaming Fee DoS DoS Acknowledged
Description
In the
_rebalancefunction the streaming fee and rebalance fee is withdrawn from the margin of the system’s account. However in cases where the streaming fee has grown to be significant and more than the available margin for the account this can result in a DoS of rebalances.Recommendation
This is an unlikely scenario however a permissioned function which can settle profits to the accounts margin can resolve this scenario if it were to ever arise.
-
L-18 Low Rebalances Can Occur While Paused Warning Acknowledged
Description
In the
LeveragedTokencontract therebalancefunction can still be called by the keeper when the contract is in a paused state. This may lead to unexpected issues when the contract is paused.Recommendation
Be aware of this behavior and consider reverting in the
rebalancefunction if the contract is paused. -
L-19 Low Order Fee Charged May Not Cover Total Fee Warning Acknowledged
Description
The order fee charged in the
computePriceImpactfunction is based on thesizeDeltaof the individual deposit or withdrawal being made. As a result it is possible for the net amount of order fees collected from depositors/withdrawers to not cover the order fees levied by the Perps V3 system upon rebalancing.This is because the
calculateOrderFeefunction in Perps V3 charges a taker fee for the size delta which flips the skew. The taker fee is larger than the maker fee and so therefore many individual order fee computations will estimate that more volume will be charged at the maker fee, when in reality when the entire rebalancesizeDeltaorder is made more volume will be charged at the higher taker fee.Recommendation
Similar to L-03, order fees can be charged based on the incremental amount that the user contributes to the overall order fee that will be levied.
Given complications with the skew changing between the order fee being charged to withdrawers and depositors, the safest approach would be to charge users the entire order fee of the rebalance sizeDelta for maximum security against fee gaming. However there is a tradeoff with excessively charging users so these options should be weighed carefully.
-
L-20 Low Leverage Not Reached Due To Pricing Discrepencies Warning Acknowledged
Description
The LeveragedToken contract uses
_getLeverageUpdateSizeDeltato calculate the size delta of the next order to maintain the intended leverage. Based on the current margin of the position, it calculates what should be the target size of the position:uint256 targetNotional = marginAmount.mul(targetLeverage).div(assetPrice_);The issue is that it divided by
(assetPrice_);rather than the exact price used by the PerpsV3 system, which may potentially differ if Perps uses a Chainlink feed for the market.Consider the following example:
Margin: $200 Intended Leverage: 2x assetPrice_: $100 SNX Price: $110
targetNotional = $200 * 2 / $100 = 4 tokens
This would return a
leverage()of 4 * $110 / $200 = 2.2x which is higher than intended for the position.Recommendation
Ensure the price feed used in PerpsV3 is also Pyth rather than Chainlink for each market a position is made, otherwise document this behavior.
Remediation Review
5 findings · December 11 to 12, 2024-
H-01 High Vault Drained By Cancellation Fees Gaming Resolved
Description
In the SNX perps market when a cancellation is performed the user who initiates the order cancellation is rewarded for invoking the transaction.
Orders can be submitted to the Perps V3 system that are immediately cancellable because the acceptablePrice is unfulfillable by the current market fill price. This is an acknowledged behavior from a previous Perps V3 audit referenced below.
The TLX vault can be placed into a state where every order committed is thereby immediately cancellable due to the skew exceeding the configured price impact tolerance.
While in this state, a malicious actor can drain the vault by intentionally minting small amounts such that an order is committed by the TLX system and then cancelling the order after the settlement delay has passed. For each cancellation the TLX vault will lose the keeper cancellation reward from it’s margin and the cancelling keeper will gain it.
Reference finding from the SNX Perps V3 audit:
Recommendation
Compare the current market fill price + a small buffer to the acceptable price. If the acceptable price is not met by the current market fill price + a small buffer then do not commit an order in the
_submitLeverageUpdatefunction. -
M-01 Medium Only Current Mint Amount Validated Validation Acknowledged
Description
In the
_validateMintAmountfunction only the current amount being minted, represented as thebaseAmountInis validated against the max market size and value validations.However several smaller mints could take place where each of the individual mint amounts remain below the max market validations, while the summation of the mints are above the max market validations. All of these mints may occur before a rebalance is triggered due to the somewhat significant deviation threshold of 25% of the margin value as a difference between OI and target OI.
Recommendation
Consider validating the current outstanding rebalance
sizeDeltaagainst the market maximums as opposed to the immediatebaseAmountInthat is currently being minted. -
L-01 Low Missing Buffer In Size Validation Validation Resolved
Description
In the
_validateMintAmountfunction there is no buffer applied to themaxMarketSizelike there is with themaxSideValuevalidation. As a result the vault’s mint amount is more likely to drift over themaxMarketSizedepending on the market price of the asset and the other interactions with the Perps V3 market outside of the TLX system.Recommendation
Consider using a buffer to reduce the
maxMarketSizeto give some wiggle room for changing Perps market conditions. -
L-02 Low Lacking safeTransfer Best Practices Acknowledged
Description
In the
recoverAssetfunction in theLinkTopupUpkeepcontract transfer is used on the arbitraryassettoken without validating the return value. This can lead to false positive successful execution of therecoverAssetfunction even when a token transfer fails for tokens that return false upon failure.Recommendation
Consider using
safeTransferfor therecoverAssetfunction. -
L-03 Low Outstanding TODOs Warning Acknowledged
Description
In the
AddressesandProxyOwnercontracts there are outstanding TODOs to update the missing addresses and to transfer ownership to theProxyOwner.Recommendation
Be sure to address these outstanding TODO comments before deploying the system.
No findings match.
More from Synthetix
All 14 reports-
Update Reviews
34 findings2 critical · 4 high 34 findings: 2 critical, 4 high, 13 medium, 10 low, 5 informational -
Deposit Contract
38 findings1 high 38 findings: 1 high, 6 medium, 20 low, 11 informational -
Fixed Staking Rewards
6 findings1 high 6 findings: 1 high, 2 medium, 3 low -
Auto-Compounding LP Vault
80 findings1 critical · 4 high 80 findings: 1 critical, 4 high, 14 medium, 61 low
Put 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.
