rules:
  - id: balancer-readonly-reentrancy-getrate
    message: $VAR.getRate() call on a Balancer pool is not protected from the read-only reentrancy.
    metadata:
      category: security
      technology:
          - solidity
      cwe: "CWE-841: Improper Enforcement of Behavioral Workflow"
      confidence: HIGH
      likelihood: MEDIUM
      impact: HIGH
      subcategory:
          - vuln
      references: 
        - https://forum.balancer.fi/t/reentrancy-vulnerability-scope-expanded/4345
    patterns:
      - pattern: |
          function $F(...) {
            ...
            $VAR.getRate();
            ...
          }
      - pattern-not-inside: |
          function $F(...) {
            ...
            VaultReentrancyLib.ensureNotInVaultContext(...);
            ...
          }
      - pattern-not-inside: |
          function $F(...) {
            ...
            $VAULT.manageUserBalance(...);
            ...
          }
      - pattern-not-inside: |
          function _updateTokenRateCache(...) {
            ...
          }
      - pattern-not-inside: |
          contract PoolRecoveryHelper {
            ...
          }
      - pattern-not-inside: |
          contract ComposableStablePoolRates {
            ...
          }
      - pattern-not-inside: |
          contract WeightedPoolProtocolFees {
            ...
          }
      - pattern-not-inside: |
            contract $C {
              ...
              function $CHECKFUNC(...) {
                ...
                VaultReentrancyLib.ensureNotInVaultContext(...);
                ...
              }
              ...
              function $F(...) {
                ...
                $CHECKFUNC(...);
                ...
                $VAR.getRate();
                ...
              }
              ...
            }
      - pattern-not-inside: |
            contract $C {
              ...
              function $CHECKFUNC(...) {
                ...
                VaultReentrancyLib.ensureNotInVaultContext(...);
                ...
              }
              ...
              function $F(...) {
                ...
                $VAR.getRate();
                ...
                $CHECKFUNC(...);
                ...
              }
              ...
            }
      - pattern-not-inside: |
            contract $C {
              ...
              function $CHECKFUNC(...) {
                ...
                $VAULT.manageUserBalance(...);
                ...
              }
              ...
              function $F(...) {
                ...
                $VAR.getRate();
                ...
                $CHECKFUNC(...);
                ...
              }
              ...
            }
      - pattern-not-inside: |
            contract $C {
              ...
              function $CHECKFUNC(...) {
                ...
                $VAULT.manageUserBalance(...);
                ...
              }
              ...
              function $F(...) {
                ...
                $CHECKFUNC(...);
                ...
                $VAR.getRate();
                ...
              }
              ...
            }
      - focus-metavariable: $VAR
    languages:
      - solidity
    severity: ERROR