SmarDex Ecosystem
Github
USDN Protocol
USDN Protocol
  • Introduction
    • Quick Overview
  • THE USDN Protocol
    • Protocol USDN Overview
      • Simplified Examples
    • Protocol Balance
      • Imbalance Protections
      • Equilibrium: The Role of the Funding Rate
    • Vault Side
      • Vault Overview
      • Rebase Mechanism
      • Yields
        • Funding Rates
        • Yield-bearing asset
    • Long Side
      • Long Perpetual
      • Long Overview
      • Dip Accumulator
      • wstETH Collateralization
      • Liquidations and Minimum Position
    • Inside the Protocol
      • Protocol vs Market Fluctuations
      • 1. Providing a Price
      • 2. Calculating Long PnLs
      • 3. Applying the Funding Rate
      • 4. Liquidating Positions
    • Integration
      • WUSDN
    • Fees
      • Protocol Fees
      • Liquidation Fee
    • Protocol parameters
    • Oracles
    • Governance
    • Risks
    • SDEX
    • Addresses
    • FAQ
    • Glossary
  • PERIPHERY
    • Long farming
  • Whitepaper
  • Github
  • Audits
Powered by GitBook
On this page
  • Guardian
  • Bailsec

Audits

PreviousWhitepaper

Last updated 1 month ago

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 liquidatefunction 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 _removeBlockedPendingActionwithout 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.

Comprehensive Smart Contract Audits | Guardian
Audits/Smardex/12-18-2024_Smardex_USDN.pdf at main · GuardianAudits/AuditsGitHub
BAIL
Logo
BailSec/Bailsec - Smardex USDN - Final Report.pdf at main · bailsec/BailSecGitHub
BailSec/Bailsec - Smardex Ecosystem - Final Report.pdf at main · bailsec/BailSecGitHub
Logo
Logo
Logo
Logo