# Reputation-Related Risk

## Reputation attack through submission of UserOp with a low gas price

If a user submits a UserOperation with a low gas price to the mempool, the bundler may not include it in the bundle due to its relatively low value, leaving it to wait in the mempool.

As a result, `opsSeen` increases while `opsIncluded` does not (check [here](https://eips.ethereum.org/EIPS/eip-7562#reputation-definitions)), which negatively impacts the reputation of the related entities. Ultimately, this can be considered an attack on the reputation system.&#x20;

The reason this type of attack is possible is that if an issue arises with the `userOp`, the reputation of the entities being referenced is reduced, unless the entity is staked.

* Mitigation: If a `userOp` remains in the mempool for an extended period, the reason should be carefully examined before deciding which entity’s reputation to decrease. Additionally, the opsSeen for entities without fault should be reduced.

{% hint style="info" %}
Although it’s specified in the [document](https://eips.ethereum.org/EIPS/eip-4337), it is a detail that service operators might overlook.
{% endhint %}

***

## Temporary DoS when signer changes

When the paymaster’s validation logic involves signing, changing the signer can temporarily cause a DoS for pending `UserOp` operations in the mempool that were signed by the old signer but have not yet been processed. This type of DoS can impact the reputation of the involved entities.

* Mitigation: Cache the value of the `oldSigner` within the `setSigner` function for temporary use.

```solidity
function setSigner(address _newVerifyingSigner) external payable override onlyOwner {
    ...
    oldSigner = verifyingSigner;
    assembly ("memory-safe") {
        sstore(verifyingSigner.slot, _newVerifyingSigner) 
    }
    ...
}
```

***

## Reputation attack through withdrawal in a singleton Paymaster

In a singleton Paymaster contract(e.g. Sponsorship paymaster), where funds are shared among multiple userOps, if the funds required for executing these `userOps` are withdrawn via the withdraw function while the `userOp`s are still in the mempool, many `userOps` may revert during the second validation due to insufficient funds, leading to a decrease in the Paymaster’s reputation.

<figure><img src="https://964345221-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fei169WYgpcSKzLw6xzlv%2Fuploads%2FC96I3aTZ6RL4JDaEyAkF%2Fimage.png?alt=media&#x26;token=e27745a5-fa47-48ed-9524-ceabee6ed638" alt=""><figcaption></figcaption></figure>

* Mitigation: To prevent a sudden lack of funds before all `userOp`s in the mempool are processed, introduce a waiting period for users, such as service operators, who have the ability to withdraw all funds via the `withdraw` function, instead of processing the withdrawal request immediately.

***

## Incorrect validation due to unupdated funds during the validation phase

If the `validatePaymasterUserOp` function does not deduct the user's funds during validation, an issue may arise during the 2nd validation phase. In the `EntryPoint` contract’s `handleOps` function, user operations within a bundle are validated through a `for` loop. Since the user’s funds deposited in the paymaster are not deducted during this process, all `userOp`s can pass validation—even if the user lacks sufficient funds.

This can lead to **underflow** when the funds are deducted in the `postOp` stage. If the calculation isn't performed within an `unchecked` block, the underflow will trigger a **revert**. Consequently, the `opsSeen` counter for the paymaster will increment, but the `opsIncluded` counter will not, leaving the paymaster vulnerable to **reputation attacks**.

* Mitigation: Deduct the user's funds during the validation phase, or add a variable to track state changes during the validation phase.

```solidity
function _validatePaymasterUserOp(
    PackedUserOperation calldata userOp,
    bytes32 userOpHash,
    uint256 requiredPreFund
)
    internal
    view
    override 
    returns (bytes memory context, uint256 validationData)
{
    ...
    
    uint256 effectiveCost = (requiredPreFund * priceMarkup) / PRICE_DENOMINATOR;
    if (effectiveCost > paymasterIdBalances[paymasterId]) {
        revert InsufficientFundsForPaymasterId();
    }
    paymasterIdBalances[paymasterId] -= effectiveCost;
    
    ...
}
```


---

# Agent Instructions: 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:

```
GET https://paymasterdocs.gitbook.io/paymasterdocs/vectors-of-paymaster/general-vectors/reputation-related-risk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
