> For the complete documentation index, see [llms.txt](https://funarchy.gitbook.io/funarchy/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://funarchy.gitbook.io/funarchy/security-for-prediction-market/operation/dos-via-unrestricted-shared-state-manipulation.md).

# DoS via Unrestricted Shared State Manipulation

### Referral Logic DoS

#### Description

This vulnerability occurs when core transaction function(e.g. `matchOrders`) are tightly coupled with auxiliary logic, such as referral programs, reward trackers, and fee calculations.

In structures where auxiliary functions are executed directly within the core logic, even minor bugs, such as simple point accumulation errors or overflows, can act as single points of failure, reverting the entire transaction.

In particular, if auxiliary logic lacks proper access control or input validation is inadequate, an attacker can intentionally corrupt internal counters or state values, causing all orders to fail from the next transaction onward.

This structural vulnerability ultimately blocks core asset transfers, leading to a Denial of Service that shut down the entire matching engine.

This issue can occur when auxiliary calculation logic such as `_allocateFees`, is included inside the matching engine, as in the code below.

{% code fullWidth="false" expandable="true" %}

```solidity
function _executeMatch(Order memory takerOrder, Order[] memory makerOrders, uint256 takerFillAmount, uint256[] memory makerFillAmounts, uint256 feeRateBpsTaker, uint256 feeRateBpsMaker, uint256 takerDiscountBps, uint256 makerDiscountBps, uint256 minFeeAmount) internal {
    ...
    if (takerPaysCollateralFee) {
        _transfer(address(this), takerOrder.maker, takerAssetId, taking - finalFee);
        // Allocate taker's fee: rebate to referrer + remaining to treasury
        _allocateFees(address(this), takerOrder.maker, finalFee, referrerRebate, referrer, 0);
    } else if (feeRateBpsMaker == 0 && finalFee > 0) {
        // taker buy conditional tokens
        // Maker has zero fee rate, taker receives outcome tokens
        // Transfer tokens to taker
        // conditional tokens in maker orders -> taker
        _transfer(address(this), takerOrder.maker, takerAssetId, taking);
        // Allocate surplus collateral as fee, taker pays fee
        _allocateFees(address(this), takerOrder.maker, finalFee, referrerRebate, referrer, 0);
    } 
    ...
}
```

{% endcode %}

#### Attack Scenario

<figure><img src="https://4210179539-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2DiVEbUgCTsp2iPassR9%2Fuploads%2FVGkyO76daF5BXHSlyt8I%2Fimage.png?alt=media&amp;token=772429e0-ae11-4c7c-93d0-efb25106d853" alt=""><figcaption></figcaption></figure>

{% stepper %}
{% step %}
The attacker  notices that function that increment internal counters (e.g. `totalVolume`), such as `proccessTradeRefferal`, are exposed publicly without separate permission checks(Modifier).
{% endstep %}

{% step %}
Theattacker repeatedly calls the function with a value close to the maximum(`type(uint256).max-1`) as a parameter, thereby randomly manipulating the `totalVolume` variable of the victim(Reffer) to be close to `2^256-1`.
{% endstep %}

{% step %}
Afterwards, when a normal trader connected to the victim attempts to make a normal transaction(`matchOrders`), the internal fee calculation logic attempts to add the incurred transaction fee to the `totalVolume`, which has already reached its limit
{% endstep %}

{% step %}
This addition operation will eventually cause an overflow(Revert) by exceeding the integer limit, and without the ability to initialize the variable, the victim's account will be permanently unalbe to trade.
{% endstep %}
{% endstepper %}

#### Real World Case Study

This case is vulnerability I personally identified and reported in the opinion. To verify this, I wrote and submitted proof-of-concept(PoC) code. The opinion prediction market acknowledged the issue, implemented mitigations, and redeployed the contract.

* Target : [Opinion](https://app.opinion.trade/trending) - `CTFExchangeFeeManager.sol`
* Vulnerable Function : `processTradeReferral()`
* Note : Discovered & PoC Submitted by Author
* Audit Report : [link](https://www.notion.so/Opinion-Prediction-Market-Audit-Report-2a7e79f13a0680e9bdf6fe7201cc9374?source=copy_link)

#### Mitigation

* **Enforce Strict Access Control**
  * All auxiliary functions that change state variable must be marked with access control modifiers such as `onlyExchange` or `onlyOperator`.
* **Decouple Auxiliary Logic**
  * Core asset transfers and order matching should be designed to operate normally even if non-core functions such as statistics recording, referral updates, and event logging fail.
* **Input Validation**
  * It is necessary to verify that the fees, volume, and referral points values transmitted from external sources do not fall outside of abnormal or unrealistic ranges.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://funarchy.gitbook.io/funarchy/security-for-prediction-market/operation/dos-via-unrestricted-shared-state-manipulation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
