Audits
Guardian
Team Response to Acknowledged Issues
M-01 | Imbalance Does Not Count Funding
We don’t need the imbalance checks to be so precise. Fundings won’t affect the imbalance in a way that would put the protocol in a critical position, so it is safe to acknowledge this from our point of view.
M-02 | Positions Opened Above Max Leverage
It is possible for a position to exceed our maximum limits, but we estimate the likelihood and feasibility to be extremely low, as it would require predicting the price in advance. Additionally, holding a position with higher leverage significantly increases the chances of liquidation for users. That being said, if certain positions slightly exceed the maximum leverage in edge cases, it does not introduce any risk to the protocol.
M-05 | Initiators Avoid A Portion Of Funding
We chose this solution because we estimated it to be the best one. It’s not perfect, but the alternative is even worse, as it would require applying funding retroactively from the last update timestamp to the position’s creation timestamp. Not only does this seem unfair, but if the last update timestamp is very old, it could result in a proportionally larger error at the user’s expense. With the current solution, the error is bounded by the Chainlink heartbeat, ensuring it remains within a reasonable magnitude. Therefore, we believe it is the safer approach.
M-06 | _triggerRebalance Does Not Account For Liquidation Rewards
According to both the auditor and us, the value sent to the liquidator is negligible compared to the protocol's balances. This does not justify the additional gas consumption.
M-13 | Exposure During Closure Unaccounted
The difference in value is negligible, and fixing it would require complex logic just to handle that case.
M-15 | Fee Change Hurts Traders
We chose not to cache all values in the case of an update made by governance. If we did, it would cost users more gas and have a low positive impact for them. We estimate the risk to be low, as updates will not happen frequently.
M-18 | No Rebalancer Trigger On Individual Liquidation
This is by design, changing this logic would mean giving users more control over the rebalancer’s trigger, and would mess with the bonus mechanism.
M-20 | Increased Liquidation Rewards
While the issue is valid, executing it profitably on a consistent basis will be virtually impossible due to the security deposit and various fees (network and protocol). Therefore, from our point of view, it is safe to acknowledge.
M-27 | Liquidatable Positions Can Be Opened
This issue will occur in a very specific case: when we recalculate the tick due to the max leverage condition, and the new tick results in a higher liquidation penalty than the first one. This would mean the position becomes instantly liquidatable. We estimate the risk to be low, and it is safe to acknowledge.
M-29 | Sandwich Liquidations
The scenarios explained in this issue are correct, but the protocol fee and the gas cost for making a deposit or a withdrawal will make this case more expensive than staying in the vault.
M-30 | Validate Withdrawal Ignores Funding
We think that fixing this issue will lead to more issues in the initialization/validation flow. The gain is low since it only accounts for the funding accumulated between initialization and validation, which is currently 24 seconds. The DoS risk exists but only in a very difficult edge case with extremely low liquidity in the protocol.
M-31 | Remove Pending Position Price Can Be Stale
This is an emergency function, requiring the price to be the latest available is not mandatory and could introduce friction is our operations during a potential incident.
M-32 | Neutral Price Used In Init Functions
The price used during initiate actions is temporary. Therefore the fact that it doesn’t use the confidence interval doesn’t matter that much. While it could be annoying for the slippage check, it would require some refactoring for a marginal benefit, so we prefer to leave it as is.
M-33 | Funding Rate Affected By Updates
We know that our funding formula works well when there is activity in the protocol. The funding rates and the protocol's balance will improve with user actions, even though these actions could potentially accentuate its imbalance. Also, the new formula from the recommendation will not work as expected.
M-34 | Old Vault Validations Swing USDN Price
The potential impact is minimal, while the fix carries a higher risk of introducing new issues.
Bailsec
Answer from the team to acknowledged issues
Issue_01 Wrong wstETH conversion
The price of stETH is almost always extremely close to the price of ETH (because they are backed 1-to-1) and there is no reason to doubt this in this particular scenario. For estimating the liquidator rewards, this simplification is satisfactory.
Issue_02 Maximum reward can be bypassed via single liquidations
The 0.5 ETH cap on the reward is already extremely high, and even with very high gas prices, it's unlikely that a single tick liquidation achieves this maximum. Furthermore, ticks are usually liquidated one at a time by automated bots as the price gradually draws down.
Issue_08 Rebalancer can remain locked due to frequent rebalances
Because users of the Dip Accumulator (Rebalancer) are exempt from position fee on entry and receive a bonus collateral reward each time it gets triggered, it's important to avoid that they can exit as soon as the reward was collected. This would nullify the rebalancing effect of this component during crucial liquidation events.
Issue_09 Possible lost funds due to accMultiplier of zero
Issue_12 Closure initiation with lastPrice does not align with validation
During closure initiation, the _lastPrice
can be more recent than the user-provided price, but never older. As such, it's a better estimate to use the _lastPrice
for the slippage check, especially knowing that most of the time, the price comes from the push-based oracle, which does not have a confidence interval anyway.
Issue_13 Funding rate inconsistency during position closures
The trade-off that was made is to allow users to use the on-chain price for initiation of the position closure, which greatly reduces gas usage compared to using a more recent low-latency price. To avoid other security issues and to remain fair to all users, the unrealized funding is extrapolated to the current timestamp for calculations, so that a user closing a position pays funding up to this moment. This is of course an estimate which can insignificantly affect the calculations of the funding for other users for a short period of time.
Issue_14 Vanilla liquidation within closure validation
Because the difference between the position value calculated during closure initiation and closure validation can only be small (they differ in time by only 24 seconds), the amount of assets that will be transferred from/to the vault for correction will not significantly affect the balance of the protocol. Furthermore, we feel that the triggering logic for the Dip Accumulator (Rebalancer) is too complex to be included in the position closure flow for only minimal benefits.
Issue_15 Opening validation liquidation check
Since the _lastPrice
can be more recent than the user-provided price (which is for a timestamp 24 seconds after their initiation), but never older, it constitutes a better price to check for a liquidation state here. Moreover, the position can be liquidated at any point and by anyone after the opening has been initiated, which greatly reduces the chances of a user dodging a liquidation.
Issue_16 PnL reset can be exploited by vault depositors to gain a benefit
The protocol has many measures in place to avoid that small changes in balance due to protocol state adjustment can profit a malicious user. Position fees and the confidence interval of the low-latency oracle are used to ensure no profit can be made for such small divergences. On the flip side, those adjustments ensure fairness to users while keeping gas costs to a minimum.
Issue_17 Lack of opening fee caching can change outcome
The position fee is rarely changed, and if changed, all efforts will be made to do it while no user has a pending action that must be validated. In most cases, the impact on the price slippage check would be very minor anyway.
Issue_18 Penalty change for maxLeverage scenario
This behavior is documented in the source code and is expected. It does not constitute a security issue as the protocol can accomodate leverages which are slightly higher than the set maximum without any problems.
Issue_19 Incorrect clamping during position closure initiation
As recommended by the auditors, we will not fix the issue.
The position value exceeding the long's balance is a pretty extreme edge case, and the extrapolation should be on at most 1 hour (Chainlink's heartbeat). Therefore, we are confident this issue is safe to acknowledge.
Issue_20 Lack of fee application during position closure
Imbalance checks are there to prevent heavy imbalance on one side, they do not need to be extremely precise. As the impact is negligible, we can safely acknowledge this issue.
Issue_21 Slippage check uses price without CI
Depending on the oracle used during the initiation phase, the price provided can not include a confidence interval. So, for the sake of consistency, it is not included in the slippage check for any oracle price.
Issue_23 Opening and SDEX fee will be lost if pending action is removed
The removal of a blocked pending action is an extreme edge case, the loss of the fee (in wstETH and SDEX) is negligible compared to the cost of storing those values for each and every action. As this does not impact other users, it is safe to acknowledge.
Issue_24 Funding rate update frequency impacts outcome
This is an accepted side effect of the current calculation, this is accurately reflected in the funding rate shown on our frontend.
Issue_25 Removal of blocked closure validation does not account for new price
If a pending action is blocked, the protocol cannot function properly. We consider it more important to act fast rather than try and get the correct round ID from Chainlink to calculate the proper value. If absolutely necessary, we can call the liquidate
function with a fresh price before removing the blocked pending action.
As this is an extreme edge case and does not impact other users, we think it is safe to acknowledge.
Issue_26 Invariant violation due to maxLongBalance clamping
The clamping of the long balance was added to avoid a potential DoS of the protocol in extreme conditions, including extended protocol inactivity with an aggressive funding and a very low average leverage. While it is not a perfect solution, we find the trade-off acceptable, and thus, the issue safe to acknowledge.
Issue_27 Removing actions without cleanup can result in several side effects
The removal of a blocked pending action without cleanup is a "last resort" functionality. While it is not ideal, it is better than having the protocol (and thus, user funds) blocked with no recourse. We are aware of the side-effect and will only use this function if there are no other solutions.
Issue_28 Stuck securityDeposit in case of blocked removal without cleanup
As previously stated in Issue_27
, we will only use _removeBlockedPendingAction
without cleanup if there are no other solutions.
Issue_29 Removal of blocked actions can imbalance the protocol
As previously stated in Issue_27
, we will only remove a pending action if it is currently blocking the whole protocol. By-passing imbalance checks is an acceptable side effect to unblocking the protocol.
Issue_30 Inconsistency in removing initiated opening
We consider that this is an acceptable case and prefer to not change the protocol logic.
Issue_31 Incorrect longBalance reset in case of outstanding bad-debt position
Addressing this would require significant changes to the underlying math. Given that this is an edge case, and if longBalance
reaches zero, the implications of this particular scenario are relatively minor compared to broader concerns.
Issue_32 Extrapolation within opening initiation can result in incorrect tick for position
As the solution to this issue is non-trivial, we've followed Bailsec recommendation and added documentation in the code.
Issue_33 maxLeverage excess within _calcRebalancerPositionTick
This issue can only occur when the penalty has been changed and the Rebalancer attempts to open a position on a tick that still has the previous penalty. While this scenario is possible, we accept that the Rebalancer may occasionally have a position with a slightly higher leverage than anticipated. Following the Bailsec recommendation, we have added code documentation to explicitly address this behavior.
Issue_34 Edge-case can result in lower leverage than expected
Like the issue 35, we acknowledge that this edge-case can happen, but we accept the fact that the Rebalancer can maybe have a lower leverage than expected.
Issue_35 Extrapolation can result in inaccurate posId.tick
The two-step action on the protocol means that extrapolations made during the initiation phase may slightly change by the validation phase. This is a design choice, and we accept these cases as part of the system's expected behavior.
Issue_36 Rebalancer leverage may often be insufficient to reach target
This is done on purpose to avoid that the Rebalancer has a high leverage, resulting in a riskier position. If the Rebalancer position gets liquidated, its balancing effect is moot. We can safely acknowledge this issue, as it is a design choice.
Issue_38 Position value can never become worth more than position expo even with funding application
Clamping the maximum position value to the position's total exposure was a deliberate design choice. As noted in the Bailsec recommendation, altering this logic would require a full rewrite of all mathematical models. For a position value to approach its total exposure would necessitate both extreme profits AND consistently increasing funding rates growing its value. We have decided to accept this outcome and acknowledge this limitation as a known issue.
Issue_39 Users can frontrun the oracle update
The user can immediately create a profitable position, but they will be locked into the protocol during at least 4 hours. This means they are exposed to price action of the underlying asset for this duration. If the Rebalancer gets triggered again, they could be locked for additional time. In any case, user profits aren't guaranteed.
Issue_40 minLongPositionCheck does not include bonus
This issue will limit, in specific cases, the opening of a Rebalancer position. We plan to fix this issue in a future update of the protocol, but in the meantime it is safe for us to acknowledge it as it does not represent a security risk for the protocol.
Issue_41 Erroneous imbalance check
Like for the issue 40, we plan to fix it in a future update.
Issue_42 Payout of liquidation rewards post rebalancing
The calculation of the liquidation reward depends on different factors, of which the Rebalancer action. Those rewards are effectively taken from the vault side, but are clamp to 0.5 ETH. So even if the payout put the protocol in an unbalanced state, it will have a minimal impact.
Issue_43 Funding is erroneously impacted by temporary bad-debt scenario
The consequences of this issue have a low impact overall. The funding rate being impacted momentarily might result in minor discrepancies in funding payments for users during this brief period.
Issue_44 Rebalancer is only triggered if there are no pending liquidations left
It's more beneficial to address and compensate for the imbalance after all liquidations have occurred, particularly when the imbalance is at its peak.
Issue_45 Bonus is incorrectly impacted by bad debt scenario
We can attribute this behavior to design choices, as we intentionally wanted to prevent the vault from incurring additional costs.
Issue_47 Hindsight changes of parameter settings
The changes to these parameters are inherently governance-related, as they require admin intervention to update. These adjustments, although impactful within their specific domains, do not generally disrupt the core functionality or stability of the protocol.
Issue_48 Change of _liquidationPenalty can result in unexpected leverage change for users
The mechanism where the liquidation penalty is stored at the time of position initiation ensures that each position retains its original penalty value throughout its lifetime. This design choice helps maintain consistency and predictability for users by ensuring they do not experience sudden changes in their positions' leverage due to external modifications.
Issue_51 Extrapolation can be different from real funding
By considering the audit recommendations, we will not apply a fix and we will continue to monitor its impact. We will stay vigilant and adapt our strategies as needed based on ongoing monitoring and analysis.
Issue_52 Pending vault validations will impact the vault state
The current approach by limiting user action imbalances and ensuring that actions are accompanied by other queued pending actions validation that have been present for more than 15 minutes helps mitigate these risks without necessitating immediate changes to the deposit and withdrawal logic.
Issue_53 Several scenarios allow for frontrunning interactions
Taking into account all the necessary conditions, such as a large position nearing liquidation and price timestamp manipulation, as well as the significant size of the refactor and the potential side effects, we have decided not to implement a fix at this time.
Issue_54 Funding adjustment can be blocked due to _pendingBalanceVault mechanism
Since changes in funding rates only occur after deposit or withdrawal validation, there is a 15-minute window where the impact can be observed. However, this temporary fluctuation is relatively minor and usually doesn’t have a significant effect on overall trading conditions.
Issue_55 Incorrect imbalance check during deposits
Imbalance checks are designed as virtual evaluations that should closely reflect the actual imbalance state of the protocol, but they do not necessarily need to be exact. The primary goal is to ensure that these checks provide a reasonably accurate representation of the system's state at the time of evaluation. In this context, while incorporating extrapolation into the imbalance check would improve accuracy, it is important to weigh the benefits against the potential complexity and risk of introducing new issues.
Issue_56 Missing slippage check for burned SDEX amount
The low SDEX fees mean slippage would only affect the burned amount by a few wei.
Last updated