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

0x52 - Price disparities between spot and perpetual pricing can heavily destabilize UXD #305

Open
github-actions bot opened this issue Jan 25, 2023 · 4 comments
Labels
Disagree With Severity The sponsor disputed the severity of this issue help wanted Extra attention is needed Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Disputed The sponsor disputed this issue's validity

Comments

@github-actions
Copy link

0x52

high

Price disparities between spot and perpetual pricing can heavily destabilize UXD

Summary

When minting UXD using PerpDepository.sol the amount of UXD minted corresponds to the amount of vUSD gained from selling the deposited ETH. This is problematic given that Perp Protocol is a derivative rather than a spot market, which means that price differences cannot be directly arbitraged with spot markets. The result is that derivative markets frequently trade at a price higher or lower than the spot price. The result of this is that UXD is actually pegged to vUSD rather than USD. This key difference can cause huge strain on a USD peg and likely depegging.

Vulnerability Detail

function deposit(
    address asset,
    uint256 amount
) external onlyController returns (uint256) {
    if (asset == assetToken) {
        _depositAsset(amount);
        (, uint256 quoteAmount) = _openShort(amount);
        return quoteAmount; // @audit this mint UXD equivalent to the amount of vUSD gained
    } else if (asset == quoteToken) {
        return _processQuoteMint(amount);
    } else {
        revert UnsupportedAsset(asset);
    }
}

PerpDepository#deposit shorts the deposit amount and returns the amount of vUSD resulting from the swap, which effectively pegs it to vUSD rather than USD. When the perpetual is trading at a premium arbitrage will begin happening between the spot and perpetual asset and the profit will be taken at the expense of the UXD peg.

Example:
Imagine markets are heavily trending with a spot price of $1500 and a perpetual price of $1530. A user can now buy 1 ETH for $1500 and deposit it to mint 1530 UXD. They can then swap the UXD for 1530 USDC (or other stablecoin) for a profit of $30. The user can continue to do this until either the perpetual price is arbitraged down to $1500 or the price of UXD is $0.98.

Impact

UXD is pegged to vUSD rather than USD which can cause instability and loss of peg

Code Snippet

https://github.com/sherlock-audit/2023-01-uxd/blob/main/contracts/integrations/perp/PerpDepository.sol#L240-L253

Tool used

Manual Review

Recommendation

I recommend integrating with a chainlink oracle and using its price to determine the true spot price of ETH. When a user mints make sure that the amount minted is never greater than the spot price of ETH which will prevent the negative pressure on the peg:

function deposit(
    address asset,
    uint256 amount
) external onlyController returns (uint256) {
    if (asset == assetToken) {
        _depositAsset(amount);
        (, uint256 quoteAmount) = _openShort(amount);

+       spotPrice = assetOracle.getPrice();
+       assetSpotValue = amount.mulwad(spotPrice);

-       return quoteAmount;
+       return quoteAmount <= assetSpotValue ? quoteAmount: assetSpotValue;
    } else if (asset == quoteToken) {
        return _processQuoteMint(amount);
    } else {
        revert UnsupportedAsset(asset);
    }
}
@github-actions github-actions bot added the High A valid High severity issue label Jan 25, 2023
@WarTech9
Copy link

It's a design decision to use the PERP price to determine mint/redeem amounts.
We can add oracle pricing in the future to be more robust, but that is not a priority at this moment.

@WarTech9 WarTech9 added Sponsor Disputed The sponsor disputed this issue's validity help wanted Extra attention is needed labels Jan 26, 2023
@acamill
Copy link

acamill commented Jan 28, 2023

This is a known issue on Solana implementation too.
Over the course of the year this offset due to the spread between spot and perp prices always went back to 0.
But this is something that we have in mind for later

@WarTech9 WarTech9 added the Disagree With Severity The sponsor disputed the severity of this issue label Feb 1, 2023
@hrishibhat
Copy link
Contributor

This is a valid issue in case of certain market conditions or manipulations for the vUSD to trade away from the peg.
Considering this issue as a valid medium.

@hrishibhat hrishibhat added Medium A valid Medium severity issue Disagree With Severity The sponsor disputed the severity of this issue and removed Disagree With Severity The sponsor disputed the severity of this issue High A valid High severity issue labels Feb 2, 2023
@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label Feb 2, 2023
@IAm0x52
Copy link
Collaborator

IAm0x52 commented Feb 24, 2023

Sponsor has acknowledged this risk

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Disagree With Severity The sponsor disputed the severity of this issue help wanted Extra attention is needed Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Disputed The sponsor disputed this issue's validity
Projects
None yet
Development

No branches or pull requests

5 participants