0.3.7 • Published 9 months ago

forta-hard-rugpull v0.3.7

Weekly downloads
-
License
-
Repository
github
Last release
9 months ago

Hard Rugpull Detection Agent

Description

This agent attempts to detect various types of hard rugpulls: 1. Honeypot: Token holders are unable to transfer their tokens. 2. Hidden Mints: Tokens can be minted using hidden functions. 3. Fake Ownership Renunciation: Renounced owners can recover ownership. 4. Hidden Fee Modifier: Transfer fees can be modified using hidden functions. 5. Hidden Transfer: Tokens can be transferred by others without permission. 6. Hidden Transfer Reverts: Transfer transactions can be reverted using changeable parameters.

Currently, this agent uses invariant testing to detect the above-mentioned rugpulls. Invariant testing uses a set of invariants to test the correctness of a smart contract. For example, to detect HiddenMints, the following invariant can be used:

assert(totalSupply() == initialSupply)

Supported Chains

The agent supports all chains that Forta supports.

Alerts

When one of the above-mentioned rugpulls is detected, the following alert is fired:

  • HARD-RUG-PULL-{RUGPULL_CATEGORY}-DYNAMIC
    • Fired when a created token contract is detected to be suspicious.
    • Severity: Medium
    • Type: Suspicious
    • Metadata:
      • attacker_deployer_address: The address of the attacker's deployer contract.
      • token_contract_address: The address of the token contract.
      • reason: The reason for the alert.
      • counterexample: An example sequence of function calls that trigger the alert.

The following rugpull categories are supported:

  • HONEYPOT
  • HIDDENMINTS
  • FAKEOWNERSHIPRENOUNCIATION
  • HIDDENTRANSFERS
  • HIDDENFEEMODIFIERS
  • HIDDENTRANSFERREVERTS

When two or more of the above-mentioned rugpulls are detected, the agent will additionally fire the following alert:

  • HARD-RUG-PULL-1
    • Fired when a created token contract is detected to be suspicious.
    • Severity: High
    • Type: Suspicious
    • Metadata:
      • attacker_deployer_address: The address of the attacker's deployer contract.
      • token_contract_address: The address of the token contract.

How to Read the Counterexample and the Reason

Example:

{
  "attacker_deployer_address":"0xfb941dd93dac213ecb38d6728901ce20234acac5",
  "counterexample":"{\"Sequence\":[{\"sender\":\"0x7fa9385be102ac3eac297483dd6233d62b3e1496\",\"addr\":\"0x5615deb798bb3e4dfa0139dfa1b3d433cc23b72f\",\"calldata\":\"0xec28438a0000000000000000000000000000000000000000000000000000000000000001\",\"signature\":\"setMaxTxAmount(uint256)\",\"contract_name\":\"test/test.sol:NETWORK\",\"traces\":{\"arena\":[{\"parent\":null,\"children\":[],\"idx\":0,\"trace\":{\"depth\":0,\"success\":true,\"contract\":null,\"label\":null,\"caller\":\"0x7fa9385be102ac3eac297483dd6233d62b3e1496\",\"address\":\"0x5615deb798bb3e4dfa0139dfa1b3d433cc23b72f\",\"kind\":\"CALL\",\"value\":\"0x0\",\"data\":{\"Raw\":\"0xec28438a0000000000000000000000000000000000000000000000000000000000000001\"},\"output\":{\"Raw\":\"0x\"},\"gas_cost\":7457,\"status\":\"Stop\",\"call_context\":null,\"steps\":[]},\"ordering\":[]}]}}]}",
  "reason":"Transfer amount exceeds the maxTxAmount.",
  "token_contract_address":"0x1e9804d7a48F661871eFcdE4669b39263f47F3e4"
}

The sequence is an ordered list of transactions that trigger the rugpull. If you deploy a new contract and execute transactions as the sequence suggests, you will end up triggering the hard rugpull. In this example, it is the HiddenTransferReverts rugpull. The reason field gives the exact reason for the rugpull (in this case, it is because the transfer is reverted due to the error "Transfer amount exceeds the maxTxAmount", where maxTxAmount is set by the setMaxTxAmount function). In other words, if the deployer calls the setMaxTxAmount function with 0, the transfer of the token is effectively disabled because no transfer can be made, causing a hard rugpull.

Running Locally

Prerequisites

  • nvm
  • Node.js
  • npm
  • Forta CLI
  • Docker (for containerized testing)

Environment Variables

The following environment variables are required in an .env file (referencing the .env.example file):

EVM_RPC
TESTING

Steps

  1. Clone the repository:

    git clone git@github.com:Soptq/forta-hard-rugpull.git
    cd forta-hard-rugpull
  2. Install the currently supported Node.js version using nvm:

    nvm install
    nvm use
  3. Install the current version of Foundry and follow the post-install steps output:

    curl -L https://foundry.paradigm.xyz | bash
  4. Install dependencies:

    npm install
  5. Create a .env file from the .env.example file and add your API keys:

    cp .env.example .env
  6. Start the development server:

    npm run start

Running with Docker

To run the project using Docker, follow these steps:

  1. Build the Docker containers:

    docker-compose build --build-arg INSTALL_DEV=true --build-arg NODE_ENV=development
  2. Start the containers:

    docker-compose up

This will build and start all services defined in the Docker Compose file. You can access the services locally as defined in the Docker Compose configuration.

Testing

To test a specific transaction (positive example), run:

npm run tx <transaction_id>

To test a token contract locally: 1. Get the transaction ID that deploys the token. 2. In the handleTransaction() function in agent.js, change false to true in the provideHandleTransaction() call:

```js
// return await provideHandleTransaction(txEvent, false);
return await provideHandleTransaction(txEvent, provider, true);
```
  1. Run:
    npm run tx <transaction_id> chainId <chain_id>

License

This project is licensed under the Forta Bot License 1.0. See the LICENSE file for details.