npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, πŸ‘‹, I’m Ryan HefnerΒ  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you πŸ™

Β© 2024 – Pkg Stats / Ryan Hefner

@octane-security/solgrep-ts

v0.0.42

Published

[<img width="200" alt="get in touch with Consensys Diligence" src="https://user-images.githubusercontent.com/2865694/56826101-91dcf380-685b-11e9-937c-af49c2510aa0.png">](https://diligence.consensys.net)<br/> <sup> [[ 🌐 ](https://diligence.consensys.net

Downloads

583

Readme

[ 🌐 πŸ“© πŸ”₯ ]

🧠 SolGrep - A scriptable semantic grep utility for solidity

So you have a set of smart contracts and want to find all contracts that have a public method named withdrawEth but lexical grep yields a lot of false-positives? Here's where solgrep can help! πŸ™Œ

πŸ’Ύ npm install -g solgrep

Solgrep recursively finds smart contracts in a target directory, parses the source units to understand the language semantics, and makes this information available to a powerful javascript-based filter function. This way, you can:

  • extract semantic information from solidity source code based on custom filter functions
  • find target contracts based on a custom filter script you define
  • create & run your own or built-in rules (e.g. for CI checks)
  • crunch numbers and generate statistics from a code base
  • find doppelgangers! i.e. duplicate contracts sharing the same code structure (AST_EXACT and AST_FUZZY matching)

Probably the most common way to use this tool is to run it with the --find=<js-filter-statement> option, where js-filter-statement is a javascript one-liner that tells the engine what you are interested in. You either provide a statement that returns boolean ("find mode") or return information you want to extract ("extract mode").

solgrep2

⚠️ Make sure to only allow trusted inputs to --find=<js-filter-statement> as this argument is being evaluated as javascript!

⚠️ Check out the proper order for arguments when using --find, --rule. See Usage.

Examples

Run the default rules and display some stats?

β‡’  solgrep <folder> 

Run a specific or multiple built-in rules (solgrep -l to list available rules)? πŸ‘‰

β‡’  solgrep <folder> --rule=IsInitializable --rule=Stats

You want to find all source-units with a contract that has a function named withdrawEth? πŸ‘‰

β‡’  solgrep <folder> --find="function.name=='withdrawEth'" 

Do the same thing but case-insensitive? πŸ‘‰

β‡’  solgrep <folder> --find="function.name.toLowerCase()=='withdraweth'" 

Find all functions that call selfdestruct? πŸ‘‰

β‡’  solgrep <folder> --find="function.callsTo('selfdestruct')"

Exctract all function names from all contracts? πŸ‘‰

β‡’  solgrep <folder> --find="function.name" 

Get a list of all external functions? πŸ‘‰

β‡’  solgrep <folder> --find="function.visibility.includes('external')"  

Find ERC777 contracts? πŸ‘‰

β‡’  solgrep <folder> --find="contract.name=='ERC777'" 

Extract all Contract names? πŸ‘‰

β‡’  solgrep <folder> --find="contract.name"

Extract all Interface names? πŸ‘‰

β‡’  solgrep <folder> --find="contract.name && contract.kind=='interface'"

Match against something in the AST? πŸ‘‰

β‡’  solgrep <folder> --find="Object.keys(function.modifiers).includes('nonReentrant')"

Lexial match a functions source code? πŸ‘‰

β‡’  solgrep <folder> --find="function.getSource().includes('hi')"

Find duplicate contracts? (AST exact and fuzzy matching) πŸ‘‰

β‡’  solgrep <folder> --rule DupeFinder

Use option --output=<output.json> to write all results to a file.

Built-In Keywords for --find

  • The sourceUnit object matches the source-file the engine is currently processing.
  • The contract object matches the contract the engine is currently processing.
  • The function object matches the function the engine is currently processing.

Available Methos

The following methods are available:

  • <sourceUnit|contract|function>.getSource() - provides access to the units source code
  • <sourceUnit|contract|function>.ast - provides direct access to the solidity-parser AST
  • function.callsTo('withdrawEth') - find all functions in all contracts that call a method named withdrawEth
  • There's even more information easily available (functions/events/pragmas/etc.). Go check out the Solidity SourceUnit/Contract/Function Wrapper Classes functionality (attribs/functions).

Special Functions

Special contract functions can be references as:

  • function.name == '__fallback__'
  • function.name == '__receiveEther__'
  • function.name == '__constructor__'

Built-In Rules

  • Stats - collects stats about how many files, contracts, unique names, etc. were processed
  • GenericGrep - is the engine behind the --find feature
  • ...

SHARING IS CARING - submit your rules!

Usage


β‡’  solgrep --help
Usage: solgrep <folder|...> [options]

Options:
  -r, --rule        Enable rules                           [array] [default: []]
  -l, --list-rules  List available rules              [boolean] [default: false]
  -f, --find        Find/Extract information using custom pattern
                                                           [array] [default: []]
  -o, --output      Write "results" as JSON to output file path.        [string]
  -h, --help        Show help                                          [boolean]
  -v, --version     Show version number                                [boolean]

⚠️ when using multi-options (--find, --rule) make sure to use this format:

β‡’  solgrep <folder|...> [options]

or

β‡’  solgrep [options] -- <folder|...> 

or else additional options might be interpreted as additional --find options!

Library

const solgrep = require('solgrep');

let sg = new SolGrep('::memory::', rules, callbacks);
sg.analyzeDir("/path/to/smart/contracts").then(() => {
    console.log("   ──────────────────────────── Results")
    console.log(sg.results)
    console.log("   ────────────────────────────")
    sgrep.close();
})

Demo

Here's an example that illustrates how to extract all function names from all sourceUnits and contracts.

β‡’  solgrep ../d0  --find='function.name' 
🧠 SolGrep v0.0.3 ready!

  Enabled Modules:
    βœ”οΈ GenericGrep          _function.name

[β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ] 100% | πŸ•™ ETA: 0s | 5/5 | 🌲 389 | πŸ”₯ 0 | πŸ—‚οΈ  ../d0

   ────────────────────────────
{
  '../d0/D0788Af7a613b81F437a51b96594A6387c7329b1_PendleLiquidityMiningBaseV2Multi.sol': [
    {
      rule: 'GenericGrep',
      tag: 'match-function: PendleLiquidityMiningBaseV2Multi.__constructor__',
      info: '__constructor__',
      loc: [Object]
    },
    {
      rule: 'GenericGrep',
      tag: 'match-function: PendleLiquidityMiningBaseV2Multi.setUpEmergencyMode',
      info: 'setUpEmergencyMode',
      loc: [Object]
    },
...

Run default Rulesets

If you provide no configuration options it will take the default built-in grep rules and crunch numbers using the stats module.

β‡’  solgrep ../d6 
🧠 SolGrep v0.0.1 starting ...


  πŸ“ ../d6
 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ 100% | ETA: 0s | 5/5

   ──────────────────────────── Results
{
  '../d6/d60a598998ed27a7C54315F2675908B628E434B1_LiquidityPool.sol': [
    {
      rule: 'IsInitializable',
      tag: 'INITIALIZEABLE',
      info: 'initialize - public initialize function; likely proxy'
    },
    {
      rule: 'IsInitializable',
      tag: 'INITIALIZEABLE',
      info: 'initialize - public initialize function; likely proxy'
    }
  ],
  '../d6/d64E77C7C6A1dcC7e302F8fe31A22745e223c39c_MyStrategy.sol': [
    {
      rule: 'IsInitializable',
      tag: 'INITIALIZEABLE',
      info: 'initialize - public initialize function; likely proxy'
    }
  ],
  undefined: [ { rule: 'Stats', tag: 'STATS', info: [Object] } ]
}
   ────────────────────────────
{
  sourceUnits: 4,
  contracts: {
    total: 13,
    names: {
      ERC20: 1,
      StrategySushiEthMimLp: 1,
      LiquidityPool: 1,
      Getter: 1,
      Governance: 1,
      LibraryEvents: 1,
      Perpetual: 1,
      Storage: 1,
      ArbiBoneman: 1,
      ERC721: 1,
      MyStrategy: 1,
      PausableUpgradeable: 1,
      SettAccessControl: 1
    }
  },
  interfaces: {
    total: 39,
    names: {
      IERC20: 1,
      IJar: 1,
      IStakingRewards: 1,
      IStakingRewardsFactory: 1,
      IMasterchef: 1,
      UniswapRouterV2: 1,
      IUniswapV2Pair: 1,
      IUniswapV2Factory: 1,
      IRewarder: 1,
      IMiniChefV2: 1,
      ILiquidityPool: 1,
      IOracle: 1,
      IAccessControl: 1,
      IGovernor: 1,
      IPoolCreatorFull: 1,
      ISymbolService: 1,
      IPoolCreator: 1,
      ITracer: 1,
      IVersionControl: 1,
      IVariables: 1,
      IKeeperWhitelist: 1,
      IProxyAdmin: 1,
      IDecimals: 1,
      ILiquidityPoolGetter: 1,
      ILiquidityPoolGovernance: 1,
      IPerpetual: 1,
      IERC721Enumerable: 1,
      IERC721: 1,
      IERC721Receiver: 1,
      IERC721Metadata: 1,
      IERC165: 1,
      ICurveGauge: 1,
      ICurveStableSwapREN: 1,
      IUniswapRouterV2: 1,
      IStrategy: 1,
      IController: 2,
      IERC20Upgradeable: 2
    }
  },
  libraries: {
    total: 31,
    names: {
      SafeMath: 1,
      SafeERC20: 1,
      BoringERC20: 1,
      EnumerableSetUpgradeable: 1,
      SafeCastUpgradeable: 1,
      AMMModule: 1,
      LiquidityPoolModule: 1,
      PerpetualModule: 1,
      SignedSafeMathUpgradeable: 1,
      Constant: 1,
      Math: 1,
      SafeMathExt: 1,
      Utils: 1,
      MarginAccountModule: 1,
      EnumerableSet: 1,
      OrderData: 1,
      CollateralModule: 1,
      TradeModule: 1,
      OrderModule: 1,
      Signature: 1,
      ECDSAUpgradeable: 1,
      Strings: 1,
      MathUpgradeable: 1,
      Address: 2,
      SafeMathUpgradeable: 2,
      AddressUpgradeable: 2,
      SafeERC20Upgradeable: 2
    }
  },
  abstract: {
    total: 13,
    names: {
      StrategyBase: 1,
      StrategySushiFarmBase: 1,
      ReentrancyGuardUpgradeable: 1,
      ERC721Enumerable: 1,
      Ownable: 1,
      ERC165: 1,
      BaseStrategy: 1,
      Context: 2,
      ContextUpgradeable: 2,
      Initializable: 2
    }
  }
}
TOTAL FILES: 5
ERRORS: 1
   ────────────────────────────



cheers πŸ™Œ 
    @tintinweb 
    ConsenSys Diligence @ https://consensys.net/diligence/
    https://github.com/tintinweb/solgrep/