Skip to content

Conversation

@CPerezz
Copy link
Contributor

@CPerezz CPerezz commented Jun 18, 2025

ERC20 Max Transfers Scenario

Notes for reviewers:
This PR should ONLY be reviewed and merged once #69 has already been.

This scenario maximizes the number of ERC20 token transfers per block to unique recipient addresses, creating state bloat through new account storage entries.

Overview

The scenario uses deployed StateBloatToken contracts from deployments.json to send the maximum possible number of ERC20 transfers per block. Each transfer sends 1 token to a unique, never-before-used address, maximizing state growth.

Features

  • Dynamic Block Gas Limit: Fetches the actual network block gas limit before starting
  • Self-Adjusting Transfer Count: Automatically adjusts the number of transfers based on actual gas usage
  • Unique Recipients: Generates deterministic unique addresses for each transfer
  • Minimum Gas Fees: Uses configured minimum gas fees (default: 10 gwei base, 5 gwei tip)
  • Round-Robin Contract Usage: Distributes transfers across multiple deployed contracts
  • Recipient Tracking: Saves all recipient addresses to recipients.json for analysis

Configuration

Command Line Flags

  • --basefee: Max fee per gas in gwei (default: 10)
  • --tipfee: Max tip per gas in gwei (default: 5)
  • --contract: Specific contract address to use (default: rotate through all)

How It Works

  1. Initialization:

    • Loads deployed contracts and private key from deployments.json
    • Sets up the deployer wallet (which holds all tokens)
    • Fetches network block gas limit
  2. Transfer Phase:

    • Calculates optimal transfer count based on gas limit
    • Generates unique recipient addresses deterministically
    • Sends transfers in batches with minimal delays
    • Uses round-robin contract selection
  3. Analysis Phase:

    • Tracks confirmed transfers and gas usage
    • Calculates actual gas per transfer
    • Adjusts transfer count for next iteration
    • Saves recipient data to file
  4. Self-Adjustment:

    • If under target gas usage: increases transfers
    • If over target gas usage: decreases transfers
    • Aims for 99.5% block utilization

State Growth Impact

Each successful transfer creates:

  • New account entry for the recipient (~100 bytes)
  • Token balance storage slot for the recipient
  • Estimated state growth: 100 bytes per transfer

Output

Recipient addresses are saved to recipients.json with:

  • Address
  • Block number
  • Tokens sent

CPerezz and others added 30 commits May 7, 2025 16:45
Includes the scenarios contemplated within statebloat as well as any
extra data about them such as gas cost metrics.
This scenario deploys contracts that are exactly 24kB in size (EIP-170 limit) to maximize state growth while minimizing gas cost.

1. Generates a contract with exactly 24,576 bytes of runtime code
2. Deploys the contract using CREATE
3. Each deployment adds:
   - 24,576 bytes of runtime code
   - Account trie node
   - Total state growth: ~24.7kB per deployment

- 32,000 gas for CREATE
- 20,000 gas for new account
- 200 gas per byte for code deposit (24,576 bytes)
- Total: 4,967,200 gas per deployment
- Remove redundant throughput flag and consolidate to contracts-per-tx
- Remove count flag and related code for cleaner interface
- Update wallet count calculation to use contracts-per-tx
- Keep only two deployment rate control methods:
  - contracts-per-tx: direct control of contracts per transaction
  - gas-per-block: calculate contracts based on target gas

The scenario now runs indefinitely until stopped, with cleaner and more
focused configuration options.
- Add validation to ensure contract deployments don't exceed block gas limit
- Check both gas-per-block and contracts-per-tx against block gas limit
- Add clear error messages when gas limits are exceeded
- Move validation to Run() function to access context
- Introduce multiple test cases for contract deployment: using contracts per block, gas per block, and handling invalid configurations.
- Update config opts to replace `contracts-per-tx` with `contracts-per-block` for better clarity.
- Add error handling for scenarios where neither gas per block nor contracts per block is set.
- Refactor gas fee parameters to align with EIP-1559 standards.
- Initialize wallet pool in the contract deployment test.
- Introduced setup and teardown for contract deployment tests.
- Updated scenario options to include a maximum transactions limit. St we can test for a single tx at a time and shortening testing time.
…to max (EIP170)

- Introduced multiple dummy functions in the StateBloatToken contract to artificially inflate bytecode size.
- Updated ABI and binary files to reflect changes in the contract structure.
- Updated the contract deployment scenario to log deployed contract addresses and gas used.
- Added functionality to write deployed addresses to a JSON file for easier tracking.
- Removed gas-per-block validation and adjusted wallet count logic.
- Improved README with instructions for running against a local Anvil node without Go tests.
…ction tracking

- Introduced a batch deployment strategy that calculates the number of contracts fitting within the block gas limit.
- Added detailed tracking for deployed contracts, including gas used and bytecode size, with structured loggin.
- Improved nonce management and transaction retry logic.
… logging

- Added functionality to save a mapping of private keys to contract addresses in a deployments.json file after each contract deployment.
- Refactored the final summary logging to focus on the deployments.json file, removing the previous detailed contract saving logic.
- imporved logging to provide insights into the total number of deployers and contracts processed.
…mprove transaction handling

- Removed unused imports and redundant fields.
- Simplified transaction processing by releasing locks earlier.
- Improved logging for transaction sending and contract deployment confirmation.
- Cleaned up nonce management by directly fetching the nonce from the client.
…djustment

- Added functionality to dynamically adjust transaction fees based on current network conditions.
- Implemented retry logic for transaction sending with exponential backoff for base fee errors.
…s_limit

- Introduced BlockDeploymentStats struct to track deployment statistics per block, including contract count, total gas used, and total bytecode size.
- Implemented real-time block monitoring for logging deployment summaries.
- Updated contract bytecode size calculations to reflect actual deployed bytecode.
- Adjusted transaction processing intervals for improved efficiency.
Revert the changes done to the original `setcodetx`.
- Move the bloating code to `eoa-delegation` under statebloat.
…ario for state bloat testing

The idea is that it performs the maximum amount of SSTORE possible with the available gas limit within a single tx execution that consumes it all.
…mentation

The scenario uses deployed StateBloatToken contracts from `deployments.json` to send the maximum possible number of ERC20 transfers per block. Each transfer sends 1 token to a unique, never-before-used address, maximizing state growth.
Signed-off-by: CPerezz <37264926+CPerezz@users.noreply.github.com>
Signed-off-by: CPerezz <37264926+CPerezz@users.noreply.github.com>
Signed-off-by: CPerezz <37264926+CPerezz@users.noreply.github.com>
Signed-off-by: CPerezz <37264926+CPerezz@users.noreply.github.com>
CPerezz added 2 commits June 19, 2025 00:27
…based rate limiting

- Set MaxPending default to 100 to fix scenario hanging at startup (was 0, preventing any transactions)
- Remove hardcoded 12-second block time assumption that caused deployments only every 2 blocks
- Implement proper block-based rate limiting that waits for actual block changes
- Set rate limit to 2x expected throughput for better network utilization
- Send transactions at expected throughput rate per block instead of arbitrary delays
…nt scenario

- Replace incorrect import 'scenariotypes' with 'scenario' package
- Update ScenarioDescriptor to use correct scenario.Descriptor type
- Fix Init method signature to match scenario.Scenario interface
- Update wallet private key access to use GetWallet().GetPrivateKey()
- Remove unused Config() method not part of the interface
- Fix walletPool references in Init method
@pk910 pk910 mentioned this pull request Jun 19, 2025
4 tasks
CPerezz added 6 commits June 23, 2025 07:26
Signed-off-by: CPerezz <37264926+CPerezz@users.noreply.github.com>
Signed-off-by: CPerezz <37264926+CPerezz@users.noreply.github.com>
Signed-off-by: CPerezz <37264926+CPerezz@users.noreply.github.com>
@CPerezz CPerezz closed this Dec 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant