hats-finance / SeeR-PM-0x899bc13919880db76edf4ccd72bdfa5dfa666fb7

1 stars 0 forks source link

Users can’t specify their partition effectively splitting their position among all the outcomes #34

Open hats-bug-reporter[bot] opened 1 month ago

hats-bug-reporter[bot] commented 1 month ago

Github username: -- Twitter username: -- Submission hash (on-chain): 0xfd1b6a2195121b5e5e259ad753c910848eafc59e45d8fc1f2c430ba0b651c11d Severity: high

Description: Description\ At the moment when the user wants to split his position, partition is set by the contract itself without an opportunity to choose resulting in a split being distributed between all the outcomes.

Attack Scenario\

Let’s consider the following scenario:

  1. The user wants to split his position into separate positions from one position.
  2. He calls one of the functions in either MainnetRouter or GnosisRouter which in their turn call internal _splitPosition().
  3. Internal function splits position among all the outcomes so that the user cannot specify the desired outcomes he wants to split on.
  4. The user left with several positions (for every outcome) even though he wanted to choose only specific ones.

Attachments

Take a look at the current _splitPosition() functionality:

Router.sol::50-54

   function _splitPosition(IERC20 collateralToken, Market market, uint256 amount) internal {
        bytes32 parentCollectionId = market.parentCollectionId();
        bytes32 conditionId = market.conditionId();

        uint256[] memory partition = getPartition(conditionalTokens.getOutcomeSlotCount(conditionId));

As you can see here, partition is formed from all the outcomes for the given conditionId so the user cannot specify anything: Router.sol::72

uint256 tokenId = getTokenId(collateralToken, parentCollectionId, conditionId, partition[j]);

Then we get tokenId for each outcome and the user is left with his position being split among all the outcomes instead of the desired ones. Moreover, some users may be able to call ConditionalTokens directly bypassing the logic of the contract and setting the desired partition. This gives certain advantages for some users over others.

Recommendation partition array has to be specified by the user instead of setting it based on the outcomesSlotCount for the given conditionId.

clesaege commented 1 month ago

Yeah, we don't support partial splits. This is not a bug but a feature request (that we don't have plans for in the near future).

rodiontr commented 1 month ago

I believe this is not true. Even if we take categorical market as an example, when users deposit DAI (to make a first split), they need to specify what outcome they bet on to be true in the future. Let's say we have a question "Who will win the election?". The point of the prediction market is to allow users to bet on CandidateA or CandidateB. But it's not realized in the current version of the protocol as the users will get tokenId for each outcome:

Otherwise, what's the purpose of the project if the users get the tokens for all outcomes. I think this is a high severity issue as the current implementation breaks the concept of predictability and violates the crucial idea behind the protocol. And this is not about partial split, that's about split at all, even the function name points to the functionality that lies behind the function.

@clesaege Can you please reconsider this?

clesaege commented 1 month ago

When I said partial splits, I meant stuff like splitting [a,b,c] into [a] and [b,c] for example.

as the users will get tokenId for each outcome:

That's definitely the expected behaviour, they can then trade those outcome tokens.

rodiontr commented 1 month ago

When I said partial splits, I meant stuff like splitting [a,b,c] into [a] and [b,c] for example.

as the users will get tokenId for each outcome:

That's definitely the expected behaviour, they can then trade those outcome tokens.

sorry, can you please explain how user will lose funds if he is not right in terms of predictability?

Let's take an example: I sold one of the “loser” outcomes tokenId. When I redeem my payout, only winning outcome is burnt. But if I hold both tokens, the same thing happens, I burn the “loser” and the “winner”. For “loser” I will not get anything and for “winner” I will get money because I am right ? But what stops me from holding both tokens and get the profit and just wait and get the winning outcome. What's partition in that case is for ? That's the way how conditional tokens work as the users need to specify the partition

clesaege commented 1 month ago

But what stops me from holding both tokens and get the profit and just wait and get the winning outcome.

You would have no profit this way, as you would just get back the underlying you put.

I think you don't understand what is a partition, you read the cte doc there.