rules:
  - id: no-slippage-check
    message: No slippage check in a Uniswap v2/v3 trade
    metadata:
      category: security
      technology:
        - solidity
      cwe: "CWE-682: Incorrect Calculation"
      confidence: MEDIUM
      likelihood: HIGH
      impact: MEDIUM
      subcategory:
          - vuln
      references:
        - https://uniswapv3book.com/docs/milestone_3/slippage-protection/
    patterns:
      - pattern-either:
          - pattern: $X.swapExactTokensForTokens($A, $LIMIT, $B, $C, $D)
          - pattern: $X.swapExactTokensForTokensSupportingFeeOnTransferTokens($A, $LIMIT, $B, $C, $D)
          - pattern: $X.swapExactTokensForETH($A, $LIMIT, $B, $C, $D)
          - pattern: $X.swapExactTokensForETHSupportingFeeOnTransferTokens($A, $LIMIT, $B, $C, $D)
          - pattern: $X.swapExactETHForTokens{$VALUE:...}($LIMIT, $A, $B, $C)
          - pattern: $X.swapExactETHForTokensSupportingFeeOnTransferTokens{$VALUE:...}($LIMIT, $A, $B, $C)
          - pattern: $X.swapTokensForExactTokens($A, $LIMIT, $B, $C, $D)
          - pattern: $X.swapTokensForExactETH($A, $LIMIT, $B, $C, $D)
          - pattern: >
              function $FUNC(...) {
                ...
                $Y = $SWAPROUTER.ExactInputSingleParams({
                  tokenIn: $A, 
                  tokenOut: $B, 
                  fee: $C, 
                  recipient: $D, 
                  deadline: $E, 
                  amountIn: $F, 
                  amountOutMinimum: $LIMIT, 
                  sqrtPriceLimitX96: 0
                });
                ...
                $X.exactInputSingle($Y);
                ...
              }
          - pattern: >
                $X.exactInputSingle($SWAPROUTER.ExactInputSingleParams({
                  tokenIn: $A,
                  tokenOut: $B,
                  fee: $C,
                  recipient: $D,
                  deadline: $E,
                  amountIn: $F,
                  amountOutMinimum: $LIMIT,
                  sqrtPriceLimitX96: 0
                }));
          - pattern: >
              function $FUNC(...) {
                ...
                $Y = $SWAPROUTER.ExactOutputSingleParams({
                  tokenIn: $A,
                  tokenOut: $B,
                  fee: $C,
                  recipient: $D,
                  deadline: $E,
                  amountOut: $F,
                  amountInMaximum: $LIMIT,
                  sqrtPriceLimitX96: 0
                });
                ...
                $X.exactOutputSingle($Y);
                ...
              }
          - pattern: >
                $X.exactOutputSingle($SWAPROUTER.ExactOutputSingleParams({
                  tokenIn: $A,
                  tokenOut: $B,
                  fee: $C,
                  recipient: $D,
                  deadline: $E,
                  amountOut: $F,
                  amountInMaximum: $LIMIT,
                  sqrtPriceLimitX96: 0
                }));
          - pattern: $X.swap($RECIPIENT, $ZEROFORONE, $AMOUNTIN, $LIMIT, $DATA)
      - metavariable-regex:
          metavariable: $LIMIT
          regex: ^(0)|(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)|(type\(uint(256)?\)\.max)|(uint(256)?\(-1)|(115792089237316195423570985008687907853269984665640564039457584007913129639935)|(2\s?\*\*\s?256\s?-\s?1)$
    languages:
      - solidity
    severity: ERROR

