Skip to content

Prevent markets getting stuck when prices don't move #16

@code423n4

Description

@code423n4

Handle

gpersoon

Vulnerability details

Impact

Suppose there is a synthetic token where the price stays constant, for example:

  • synthetic DAI (with a payment token of DAI the price will not move)
  • binary option token (for example tracking the USA elections; after the election results there will be no more price movements)

In that case assetPriceHasChanged will never be true (again) and marketUpdateIndex[marketIndex] will never increase.
This means the _executeOutstandingNextPrice* functions will never be executed, which means the market effectively will be stuck.

Proof of Concept

//https://github.com/code-423n4/2021-08-floatcapital/blob/main/contracts/contracts/LongShort.sol#L669
function _updateSystemStateInternal(uint32 marketIndex) internal virtual requireMarketExists(marketIndex) {
...
int256 newAssetPrice = IOracleManager(oracleManagers[marketIndex]).updatePrice();
int256 oldAssetPrice = int256(assetPrice[marketIndex]);
bool assetPriceHasChanged = oldAssetPrice != newAssetPrice;

if (assetPriceHasChanged || msg.sender == staker) {
  ....
  if (!assetPriceHasChanged) {   
    return;
  }
  ....
 marketUpdateIndex[marketIndex] += 1;  // never reaches this point if the price doesn't change

// https://github.com/code-423n4/2021-08-floatcapital/blob/main/contracts/contracts/LongShort.sol#L1035
function _executeOutstandingNextPriceSettlements(address user, uint32 marketIndex) internal virtual {
uint256 userCurrentUpdateIndex = userNextPrice_currentUpdateIndex[marketIndex][user];
if (userCurrentUpdateIndex != 0 && userCurrentUpdateIndex <= marketUpdateIndex[marketIndex]) { // needs marketUpdateIndex[marketIndex] to be increased
_executeOutstandingNextPriceMints(marketIndex, user, true);
_executeOutstandingNextPriceMints(marketIndex, user, false);
_executeOutstandingNextPriceRedeems(marketIndex, user, true);
_executeOutstandingNextPriceRedeems(marketIndex, user, false);
_executeOutstandingNextPriceTokenShifts(marketIndex, user, true);
_executeOutstandingNextPriceTokenShifts(marketIndex, user, false);

Tools Used

Recommended Mitigation Steps

Enhance _updateSystemStateInternal so that after a certain period of time without price movements (for example 1 day),
the entire function is executed (including the marketUpdateIndex[marketIndex] += 1;)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions