forta-hard-rugpull v0.3.7
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
Clone the repository:
git clone git@github.com:Soptq/forta-hard-rugpull.git cd forta-hard-rugpull
Install the currently supported Node.js version using nvm:
nvm install nvm use
Install the current version of Foundry and follow the post-install steps output:
curl -L https://foundry.paradigm.xyz | bash
Install dependencies:
npm install
Create a
.env
file from the.env.example
file and add your API keys:cp .env.example .env
Start the development server:
npm run start
Running with Docker
To run the project using Docker, follow these steps:
Build the Docker containers:
docker-compose build --build-arg INSTALL_DEV=true --build-arg NODE_ENV=development
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);
```
- 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.
9 months ago