<!-- canonical: https://0xsimao.com/findings/yieldoor-activity-incorrect-vulnerable-price -->

# `Strategy::checkPoolActivity()` incorrect check leads to vulnerable price

Medium · Sherlock · CLMM · 24th February 2025

Finding M-4 of the Yieldoor competition.

- Protocol: https://audits.sherlock.xyz/contests/791
- Report: /reports/yieldoor
- Codebase: https://github.com/0xsimao/2025-02-yieldoor/tree/b5a0f779dce4236b02665606adb610099451a51a
- Source: https://github.com/sherlock-audit/2025-02-yieldoor-judging/issues/96

---

### Summary

`Strategy::checkPoolActivity()` [reverts](https://github.com/sherlock-audit/2025-02-yieldoor/blob/main/yieldoor/src/Strategy.sol#L322-L324) if the timestamp is 0. However, this will never happen. What actually happens is the timestamp being 1, when the cardinality has been increased and the tick timestamp was [set](https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/Oracle.sol#L118) to 1 for gas saving purposes.

When this tick is hit in the loop, it means there were not enough observations to reach the `lookAgo` timestamp and it should revert because the price could not be validated. However, if the timestamp is 1, it may not revert depending on the value of the tick delta calculated, and as the timestamp is 1, it will [return true](https://github.com/sherlock-audit/2025-02-yieldoor/blob/main/yieldoor/src/Strategy.sol#L335-L337) with an invalid price observation.

### Root Cause

In `Strategy:322`, the [timestamp check](https://github.com/sherlock-audit/2025-02-yieldoor/blob/main/yieldoor/src/Strategy.sol#L322-L324) is incorrect.

### Internal Pre-conditions

None.

### External Pre-conditions

None.

### Attack Path

1. Twap would not have enough credibility and rebalancing would be impossible.
2. Attacker or user adds cardinality to the uniswap pool, which sets the next ticks timestamp to 1.
3. Rebalance goes through with an invalid price with not enough validation, leading to depositing liquidity at a bad price and causing losses for users.

### Impact

Loss of funds due to depositing liquidity at an unfavourable price.

### PoC

The following function is used when cardinality is increased in the pool.
```solidity
    function grow(
        Observation[65535] storage self,
        uint16 current,
        uint16 next
    ) internal returns (uint16) {
        require(current > 0, 'I');
        // no-op if the passed next value isn't greater than the current next value
        if (next <= current) return current;
        // store in each slot to prevent fresh SSTOREs in swaps
        // this data will not be used because the initialized boolean is still false
        for (uint16 i = current; i < next; i++) self[i].blockTimestamp = 1;
        return next;
    }
```

### Mitigation

```solidity
            if (timestamp == 1) {
                revert("timestamp 1");
            }
```

---

Related findings:

- [Attacker can trigger temporary shutdown due to RedStonePriceFeedBase missing gas check](https://0xsimao.com/findings/felix-temporary-shutdown-price-gas): Felix Price Feeds
- [tin in the Psm will cause an instant drop in the share price which could be leveraged by Maple Pool users](https://0xsimao.com/findings/maple-finance-iv-instant-drop-share-price): Maple Cash Strategies
- [Partially removing liquidity may underflow if the price of the pool has changed significantly](https://0xsimao.com/findings/nftperp-i-partially-underflow-price-significantly): Nftperp Exchange
- [Uniswap v4 pool initialization can be frontrunned, setting an arbitrary price, and stealing tokens](https://0xsimao.com/findings/spirit-protocol-uniswap-initialization-frontrunned-price): Spirit Protocol
