Skip to content
This repository has been archived by the owner on May 26, 2023. It is now read-only.

xiaoming90 - Debt decay interval can be larger than the total duration #39

Closed
sherlock-admin opened this issue Nov 17, 2022 · 1 comment

Comments

@sherlock-admin
Copy link
Contributor

xiaoming90

medium

Debt decay interval can be larger than the total duration

Summary

The debt decay interval can be larger than the total duration of the market, which might cause some issues.

Vulnerability Detail

The following code shows that the debtDecayInterval is calculated by multiplying the params_.depositInterval by 5 in Line 185.

https://github.com/sherlock-audit/2022-11-bond/blob/main/src/bases/BondBaseSDA.sol#L180

File: BondBaseSDA.sol
180:             // The debt decay interval is how long it takes for price to drop to 0 from the last decay timestamp.
181:             // In reality, a 50% drop is likely a guaranteed bond sale. Therefore, debt decay interval needs to be
182:             // long enough to allow a bond to adjust if oversold. It also needs to be some multiple of deposit interval
183:             // because you don't want to go from 100 to 0 during the time frame you expected to sell a single bond.
184:             // A multiple of 5 is a sane default observed from running OP v1 bond markets.
185:             uint32 userDebtDecay = params_.depositInterval * 5;
186:             debtDecayInterval = minDebtDecayInterval > userDebtDecay
187:                 ? minDebtDecayInterval
188:                 : userDebtDecay;

The debt decay interval determines how long it takes for the price to drop to 0 from the last decay timestamp. However, it might be possible for a market marker to define a params_.depositInterval that results in the derived debtDecayInterval being larger than the total duration of the market.

Assume that the parameters of the SDAM:

  • params_.depositInterval = 5 days (Debt decay interval - ID in whitepaper)
  • secondsToConclusion = 10 days (Total Duration - L in whitepaper)

In this case, the debtDecayInterval will end up being 25 days (5 days * 5), which is larger than the secondsToConclusion .

Impact

The price can never drop to 0 within the market period, and the price will decay at an extremely slow rate in some cases. As a result, the sale of the bond tokens might be affected as the price of the bond tokens will remain high for a long period and will not be able to adjust itself according to the economic condition to attract potential takers.

Additionally, it appears that various parts of the calculation depend on scaling a variable with the ratio of the debt decay interval to the total duration. This issue will cause the scaling ratio to go above one (ratio > 1). If the scaling ratio does not intend to be larger than one (ratio > 1), it might break some of the properties of the market.

The following attempt to scale the capacity by the ratio of the debt decay interval to the total duration, as shown below. Taken from Page 5 of the whitepaper - Definition 8

image-20221116175141093

The following attempt to scale the time-neutral capacity by the ratio of the debt decay interval to the total duration, as shown below. Taken from Page 6 of the whitepaper - Definition 12

image-20221116175108232

Code Snippet

https://github.com/sherlock-audit/2022-11-bond/blob/main/src/bases/BondBaseSDA.sol#L180

Tool used

Manual Review

Recommendation

Review the following about the market design:

  • Determine if the market design allows the debt decay interval to be larger than the total duration
  • Determine if the market design allows the scaling ratio to go above one.

If the debt decay interval should not be larger than the total duration, implement the following validation check

uint32 secondsToConclusion;
uint32 debtDecayInterval;
{
    // Conclusion must be later than the current block timestamp or will revert
    secondsToConclusion = uint32(params_.conclusion - block.timestamp);
    if (
        secondsToConclusion < minMarketDuration ||
        params_.depositInterval < minDepositInterval ||
        params_.depositInterval > secondsToConclusion
    ) revert Auctioneer_InvalidParams();

    // The debt decay interval is how long it takes for price to drop to 0 from the last decay timestamp.
    // In reality, a 50% drop is likely a guaranteed bond sale. Therefore, debt decay interval needs to be
    // long enough to allow a bond to adjust if oversold. It also needs to be some multiple of deposit interval
    // because you don't want to go from 100 to 0 during the time frame you expected to sell a single bond.
    // A multiple of 5 is a sane default observed from running OP v1 bond markets.
    uint32 userDebtDecay = params_.depositInterval * 5;
    debtDecayInterval = minDebtDecayInterval > userDebtDecay
        ? minDebtDecayInterval
        : userDebtDecay;
+        
+   require(debtDecayInterval <= secondsToConclusion, "Invalid debtDecayInterval")

Additionally, it is recommended to define the possible range of the debt decay interval in the whitepaper (e.g. 0 < ID <= T) so that the reader can understand if the market design intends the debt decay interval to be larger than the total duration.

@Evert0x
Copy link

Evert0x commented Nov 17, 2022

Message from sponsor


The market design allows for debt decay interval to be larger than the market duration. Debt can be scaled to less than or greater than the market capacity. Having a decay interval longer than duration will mean that the deposit interval is relatively large and will allow larger purchases to fill market capacity.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants