DelegateCall - Proxy Pattern

Call a function through a proxy contract that uses delegatecall to execute logic from an implementation contract.

Technical context:
- The proxy contract forwards calls to an implementation contract using delegatecall
- DelegateCall executes the implementation's code in the proxy's context
- Storage changes affect the proxy contract, not the implementation
- msg.sender remains the original caller
- Function signature: setValue(uint256 value)
- Function selector: 0x55241077 (keccak256('setValue(uint256)') first 4 bytes)
- Recommended gas limit: 100000

Key considerations:
- You call the PROXY contract, not the implementation contract
- The proxy forwards your call using delegatecall
- Use encode the function call('setValue', [value]) to encode
- Set transaction 'to' to the PROXY address
- Set transaction 'value' to 0 (not sending BNB)
- The value will be stored in the proxy's storage

DelegateCall explained:
- Regular call: Implementation contract modifies its own storage
- DelegateCall: Implementation's code runs, but modifies caller's (proxy's) storage
- This is the foundation of upgradeable contracts

Success criteria:
- Transaction executes successfully
- Correct proxy contract is called
- Correct function selector is used
- Value is stored in the PROXY contract (not implementation)
- Implementation contract's storage remains unchanged

Call the setValue function on the proxy contract at {proxy_address} with value {value}

Set the value to {value} using the proxy contract {proxy_address}

Execute setValue({value}) through the proxy at {proxy_address}

I want to call setValue on proxy {proxy_address} and pass {value}

Implementation contract address (contains logic)

Implementation contract for verification

Proxy contract address (uses delegatecall)

Use dynamically deployed proxy contract from environment

Value to set (uint256)

Transaction executed successfully

Transaction calls PROXY contract (not implementation)

Correct setValue function signature

Value stored in PROXY contract

Implementation contract storage remains unchanged

Proxy contract must exist

Implementation contract must exist

Tests understanding of delegatecall and proxy patterns

Understanding delegatecall is crucial for upgradeable contracts and many DeFi protocols

Technical context:

- Recommended gas limit: 100000

Key considerations:

DelegateCall explained:

Success criteria:

- Transaction executes successfully

- Correct proxy contract is called

- Correct function selector is used

Value to set (uint256)

DelegateCall - Proxy Pattern

Transaction executed successfully

Correct setValue function signature

Value stored in PROXY contract

Proxy contract must exist

Implementation contract must exist


Payable Fallback - Send BNB to Contract

Send BNB directly to a contract without calling any specific function.
This will trigger the contract's receive() or fallback() function.

Technical context:
- When you send BNB to a contract without calldata, it triggers receive() if it exists
- If receive() doesn't exist, it triggers fallback() if it's payable
- The transaction 'to' field is the contract address
- The 'value' field contains the BNB amount to send
- The 'data' field should be empty (0x) or omitted
- Recommended gas limit: 100000

Fallback vs Receive:
- receive() external payable: Called when BNB is sent with empty calldata
- fallback() external payable: Called when function doesn't exist or as fallback for receive()
- At least one must be payable for the contract to receive BNB

Key considerations:
- Do NOT include any function call data
- Set transaction 'value' to the BNB amount (in wei)
- Leave 'data' field empty or set to '0x'
- The contract must have a payable receive() or fallback() function

Success criteria:
- Transaction executes successfully
- Correct contract address is used
- Correct BNB amount is sent
- No function call data (empty data field)
- Contract balance increases by the sent amount

Send {amount} BNB to the contract at {contract_address}

Transfer {amount} BNB to contract {contract_address} without calling any function

I want to send {amount} BNB directly to {contract_address}

Send {amount} BNB to {contract_address} (no function call)

Amount of BNB to send

Contract address with payable fallback/receive

Use dynamically deployed FallbackReceiver contract from environment

Transaction executed successfully

Transaction sent to correct contract

Correct BNB amount sent

No function call data (empty or 0x)

Contract balance increased by sent amount

Contract must exist

Agent must have sufficient BNB balance

Tests understanding of fallback/receive functions

Understanding fallback/receive is important for contract interactions and DeFi protocols

Technical context:

- Recommended gas limit: 100000

Fallback vs Receive:

Key considerations:

- Do NOT include any function call data

Success criteria:

- Transaction executes successfully

- Correct contract address is used

- Correct BNB amount is sent

Amount of BNB to send

Payable Fallback - Send BNB to Contract

Transaction executed successfully

Transaction sent to correct contract

Correct BNB amount sent

No function call data (empty or 0x)

Contract must exist

Agent must have sufficient BNB balance


ERC20 FlashLoan - Execute Flash Loan

Execute a flash loan by calling the FlashLoan contract's executeFlashLoan function.

Technical context:
- Flash loan allows borrowing tokens without collateral in a single transaction
- The loan must be repaid with a fee (0.3%) in the same transaction
- Function signature: executeFlashLoan(address token, uint256 amount)
- Before calling, you must approve the flash loan contract to pull back tokens
- The approval amount should be: loan amount + fee
- After the flash loan call, the contract will transfer tokens to you, then pull them back with fee
- If repayment fails, the entire transaction reverts
- Recommended gas limit: 300000

Transaction flow:
1. Calculate repayment amount: amount + (amount * 0.003)
2. Approve flash loan contract for repayment amount
3. Call executeFlashLoan(token_address, amount)
4. Contract transfers tokens to you (loan)
5. Contract immediately pulls back loan + fee

Key considerations:
- You must have enough tokens to pay the fee
- The flash loan contract must have sufficient liquidity
- Set 'to' to the flash loan contract address
- Set 'value' to 0 (not sending BNB)
- The transaction data should contain the encoded executeFlashLoan call
- Use EIP-1559 transaction type (type: 2)

Execute a flash loan of {amount} {token_symbol} from the flash loan contract at {flashloan_contract_address}. The loan must be repaid with {fee_percentage}% fee in the same transaction.

Borrow {amount} {token_symbol} using flash loan from contract {flashloan_contract_address}, use the funds, and repay with fee.

Take a flash loan of {amount} {token_symbol} tokens from {flashloan_contract_address}. Remember to approve the contract to pull back the loan amount plus {fee_percentage}% fee.

I need to execute a flash loan: borrow {amount} {token_symbol} from {flashloan_contract_address} and repay it with the {fee_percentage}% fee in one transaction

Amount to borrow (in token units)

Flash loan fee percentage

Flash loan provider contract address

Use dynamically deployed flash loan contract from environment

Token address to borrow (USDT)

USDT on BSC

Token decimals

BSC USDT uses 18 decimals (different from Ethereum USDT which uses 6)

Token symbol for natural language

Transaction executed successfully

Transaction calls correct flash loan contract

Correct executeFlashLoan function signature

Flash loan fee paid correctly

Agent balance should decrease by fee amount only

Flash loan contract must exist

Agent must have enough tokens to pay fee

Flash loan pool must have sufficient liquidity

Agent must approve flash loan contract before calling executeFlashLoan

Demonstrates understanding of flash loans, approvals, and atomic transactions

Technical context:

- Recommended gas limit: 300000

Transaction flow:

Key considerations:

- Set 'value' to 0 (not sending BNB)

Amount to borrow (in token units)

Flash loan fee percentage

Flash loan provider contract address

Token address to borrow (USDT)

USDT on BSC

Token decimals

Token symbol for natural language

ERC20 FlashLoan - Execute Flash Loan

Transaction executed successfully

Flash loan fee paid correctly

Flash loan contract must exist


Query Current Block Number

Query the current block height of the blockchain by calling eth_blockNumber RPC method. This is a fundamental blockchain query that returns the latest block number, useful for tracking blockchain state, calculating block intervals, and determining transaction timing. The block number increases with each new block mined.

Get the current block number of the blockchain

Retrieve the most recent block number from the chain

Block number must be a valid positive integer

Understand the eth_blockNumber RPC method

Learn how to query blockchain state without contracts

Learn about block-based timing mechanisms

eth_blockNumber returns the latest block number as hex string

Block number always increases (never decreases)

Different nodes may return slightly different values due to sync status

This is a lightweight RPC call with minimal overhead

Block number can be used to estimate time (BSC: ~3 seconds per block)

Useful for checking if transaction has been mined

Returns the block number at the time of query, not a specific block

Query Current Block Number


Query Gas Price

Query the current gas price and EIP-1559 fee parameters by calling eth_gasPrice or getFeeData() methods. This returns the current network gas pricing information including maxFeePerGas and maxPriorityFeePerGas for EIP-1559 transactions. Understanding gas prices is crucial for estimating transaction costs and optimizing transaction submission timing.

Get the current gas price of the network

Query the current EIP-1559 fee parameters

Check what is the current maxFeePerGas and maxPriorityFeePerGas

Retrieve the current gas pricing information

Missing required EIP-1559 fields in query result

Gas prices must be valid positive values

Understand the eth_gasPrice and getFeeData RPC methods

Learn about EIP-1559 gas pricing mechanism

Master maxFeePerGas and maxPriorityFeePerGas parameters

Understand how to optimize transaction gas costs

Learn about base fee and priority fee concepts

EIP-1559 introduced a new gas pricing mechanism with base fee + priority fee

maxFeePerGas = base fee + maxPriorityFeePerGas (tip)

maxPriorityFeePerGas is the tip paid to miners/validators

BSC supports EIP-1559 since the Bruno hard fork

Gas prices fluctuate based on network demand

getFeeData() returns both EIP-1559 and legacy gas price

Prices are returned in wei (1 Gwei = 10^9 wei)

Higher priority fee means faster transaction inclusion

Base fee is burned, priority fee goes to validators

Query Gas Price


Query Transaction Count (Nonce)

Query the transaction count (nonce) for a specific address by calling eth_getTransactionCount. The nonce represents the number of transactions sent from an address and is critical for transaction ordering and replay protection. Understanding the difference between 'pending' and 'latest' states is important: 'pending' includes pending transactions and should be used when preparing new transactions, while 'latest' only includes confirmed transactions.

Get the transaction count (nonce) for address {{query_address}}

Query the nonce for address {{query_address}}

Check how many transactions address {{query_address}} has sent

Retrieve the current nonce for address {{query_address}}

Address to query transaction count for

Nonce must be a valid non-negative integer

Understand the eth_getTransactionCount RPC method

Learn about nonce and its role in transaction ordering

Master the difference between 'pending' and 'latest' states

Nonce increments by 1 for each transaction sent

Use 'pending' state when preparing new transactions

Use 'latest' state for confirmed transaction count

Nonce must be sequential - gaps will cause transactions to be stuck

Same nonce can be used to replace a pending transaction (with higher gas)

Different providers may have slightly different pending nonces

Smart contracts do not have nonces (only EOAs do)

Nonce is per-address, not per-transaction

Address to query transaction count for

Query Transaction Count (Nonce)


Simple Contract Call - Increment Counter

Call a simple contract function without parameters.

Technical context:
- The target contract is a SimpleCounter with an increment() function
- Function signature: increment() (no parameters, no return value)
- This is a state-changing function that increases a counter by 1
- Function selector: 0xd09de08a (keccak256('increment()') first 4 bytes)
- Recommended gas limit: 50000

Key considerations:
- Create a Contract instance with the contract address and ABI
- Use encode the function call('increment', []) to encode the call
- Set transaction 'to' to the contract address
- Set transaction 'data' to the encoded function call
- Set transaction 'value' to 0 (not sending BNB)
- The contract will emit a CounterIncremented event with the new value

Success criteria:
- Transaction executes successfully
- Correct contract is called
- Correct function selector is used
- Counter value increases by 1

Call the increment() function on the contract at {contract_address}

Increment the counter in the smart contract {contract_address}

Execute the increment function on contract {contract_address}

I need you to call increment() on the contract at address {contract_address}

SimpleCounter contract address

Use dynamically deployed SimpleCounter contract from environment

Transaction executed successfully

Transaction calls correct contract

Correct increment function signature

Counter value increased by 1

SimpleCounter contract must exist

A simple counter contract for testing basic contract calls

Technical context:

- Recommended gas limit: 50000

Key considerations:

Success criteria:

- Transaction executes successfully

- Correct contract is called

- Correct function selector is used

- Counter value increases by 1

SimpleCounter contract address

Transaction executed successfully

Transaction calls correct contract

Correct increment function signature

Counter value increased by 1

SimpleCounter contract must exist


Contract Call with Parameters - Set Message

Call a contract function with parameters (string argument).

Technical context:
- The target contract is a MessageBoard with a setMessage(string) function
- Function signature: setMessage(string message)
- This function accepts a string parameter and stores it
- You must encode both the function selector and the parameter data
- Function selector: 0x368b8772 (keccak256('setMessage(string)') first 4 bytes)
- Recommended gas limit: 80000 (storage write + dynamic data)

Key considerations:
- Create a Contract instance with the contract address and ABI
- Use encode the function call('setMessage', [message]) to encode the call
- Set transaction 'to' to the contract address
- Set transaction 'data' to the encoded function call (selector + encoded parameters)
- Set transaction 'value' to 0 (not sending BNB)
- String parameters are dynamically sized and require ABI encoding

Success criteria:
- Transaction executes successfully
- Correct contract is called
- Correct function selector is used
- Message is correctly stored in the contract

Call the setMessage function on contract {contract_address} with the message '{message}'

Set the message to '{message}' on the contract at {contract_address}

Update the message in contract {contract_address} to '{message}'

I want to call setMessage on contract {contract_address} and pass the string '{message}'

MessageBoard contract address

Use dynamically deployed MessageBoard contract from environment

Message to set in the contract

Hello, Blockchain!
GM, Web3!
Testing smart contract calls
Decentralization is the future
Building on BSC

Transaction executed successfully

Transaction calls correct contract

Correct setMessage function signature

Message correctly stored in contract

MessageBoard contract must exist

A simple message board contract that stores and retrieves messages

Technical context:

Key considerations:

Success criteria:

- Transaction executes successfully

- Correct contract is called

- Correct function selector is used

MessageBoard contract address

Message to set in the contract

Transaction executed successfully

Transaction calls correct contract

Correct setMessage function signature

Message correctly stored in contract

MessageBoard contract must exist


Contract Call with Value - Send BNB to Payable Function

Call a payable contract function with BNB value attached.

Technical context:
- The target contract is a DonationBox with a payable donate() function
- Function signature: donate() payable
- This function accepts BNB and records donations
- You must set the transaction 'value' field to send BNB
- Function selector: 0xed88c68e (keccak256('donate()') first 4 bytes)
- Recommended gas limit: 100000 (storage writes and event emission)

Key considerations:
- Create a Contract instance with the contract address and ABI
- Use encode the function call('donate', []) to encode the call
- Set transaction 'to' to the contract address
- Set transaction 'data' to the encoded function call
- Set transaction 'value' to the BNB amount to send (in wei)
- The contract's BNB balance will increase by the donation amount

Success criteria:
- Transaction executes successfully
- Correct contract is called
- Correct function selector is used
- Correct amount of BNB is sent
- Contract balance increases by the donation amount

Call the donate() function on contract {contract_address} and send {amount} BNB

Donate {amount} BNB to the contract at {contract_address}

Send {amount} BNB to the donate function of contract {contract_address}

I want to call donate() on contract {contract_address} with {amount} BNB attached

Amount of BNB to donate

DonationBox contract address

Use dynamically deployed DonationBox contract from environment

Transaction executed successfully

Transaction calls correct contract

Correct donate function signature

Correct amount of BNB sent

Contract balance increased by donation amount

DonationBox contract must exist

Agent must have sufficient BNB balance

A simple donation box contract that accepts BNB via payable function

Technical context:

- Function signature: donate() payable

Key considerations:

Success criteria:

- Transaction executes successfully

- Correct contract is called

- Correct function selector is used

- Correct amount of BNB is sent

Amount of BNB to donate

DonationBox contract address

Transaction executed successfully

Transaction calls correct contract

Correct donate function signature

Correct amount of BNB sent

DonationBox contract must exist

Agent must have sufficient BNB balance


ERC20 Token Approval

Approve a spender (Router or Contract) to spend your ERC20 tokens. This is a prerequisite for many DeFi operations like swapping or adding liquidity.

The approve function sets the allowance that a spender can use on behalf of the token owner.

Key Points:
- Function: approve(address spender, uint256 amount)
- Sets allowance for spender to transfer tokens on your behalf
- Does not transfer tokens, only grants permission
- Required before operations like swap, transferFrom, addLiquidity, etc.
- Common spenders: PancakeSwap Router, Staking Contracts, etc.

Transaction Requirements:
- Call approve() on the ERC20 token contract
- Pass spender address and amount to approve
- Wait for transaction confirmation
- No BNB value needed (not payable)
- Gas: ~50,000

Example Workflow:
1. Connect to ERC20 token contract
2. Call approve(spenderAddress, amountInWei)
3. Wait for confirmation
4. Verify allowance was set correctly

Approve {spender_name} to spend {amount} {token_symbol} tokens from your account.

Grant approval to {spender_name} for {amount} {token_symbol} tokens.

Set allowance of {amount} {token_symbol} tokens for {spender_name}.

Authorize {spender_name} to use up to {amount} {token_symbol} tokens on your behalf.

Agent address (token owner)

Amount to approve (in token units)

BSC Mainnet chain ID

Address to approve (spender)

Spender name for display

ERC20 token contract address

Token decimals (all BSC tokens use 18)

Token symbol for display

Forgetting to convert amount to wei (multiply by 10^decimals)

Sending BNB value with approve transaction (not needed)

Approving the token address instead of the spender address

Not waiting for transaction confirmation before checking allowance

ERC20 Token (USDT/BUSD/CAKE)

function approve(address spender, uint256 amount) external returns (bool)

function allowance(address owner, address spender) external view returns (uint256)

function balanceOf(address account) external view returns (uint256)

Spender Contract (Router/Pool)

The contract that will be approved to spend tokens

Key Points:

Transaction Requirements:

- Wait for transaction confirmation

- No BNB value needed (not payable)

- Gas: ~50,000

Example Workflow:

1. Connect to ERC20 token contract

3. Wait for confirmation

4. Verify allowance was set correctly

Allowance for spender increases by approved amount

Token balance remains unchanged (approve does not transfer)

Use the ERC20 approve function: approve(address spender, uint256 amount)

Convert the amount to wei units using token decimals (multiply by 10^18)

The spender address should be the contract that will use your tokens

No BNB value should be sent with this transaction (not payable)

After approval, use allowance() to verify: allowance(owner, spender)

Agent address (token owner)

Amount to approve (in token units)

BSC Mainnet chain ID

Address to approve (spender)

Spender name for display

ERC20 token contract address

Token decimals (all BSC tokens use 18)

Token symbol for display

ERC20 Token Approval

Allowance increased by the approved amount

Called approve(address,uint256) with correct selector

Token balance unchanged (approve does not transfer)

Transaction executed successfully without reverting


ERC20 Approve with Callback (ERC1363)

Approve an address to spend ERC20 tokens and trigger an `onApprovalReceived` callback on the spender contract if it implements `IERC1363Spender`.

Technical context:
- ERC1363 extends ERC20 with payable token functions
- Function signature: approveAndCall(address spender, uint256 value) or approveAndCall(address spender, uint256 value, bytes data)
- The spender must implement IERC1363Spender interface to receive callback
- If spender is a contract implementing IERC1363Spender, onApprovalReceived will be called
- If spender doesn't implement the interface, it works like regular approve
- Recommended gas limit: 200000

Key considerations:
- Use the deployed ERC1363 test token (T1363)
- Create a Contract instance with token address and ERC1363 ABI
- The approveAndCall function combines approve and callback in one transaction
- Set transaction 'to' to the token contract address
- Set transaction 'value' to 0 (not sending BNB)
- After approval, allowance(owner, spender) should return the approved amount

Approve {spender_address} to spend {amount} {token_symbol} tokens with callback

Use ERC1363 approveAndCall to authorize {spender_address} to use {amount} {token_symbol}

Grant approval to {spender_address} for {amount} {token_symbol} using the ERC1363 token's callback feature

Approve {amount} {token_symbol} for {spender_address} with automatic onApprovalReceived callback

Amount of tokens to approve

Address to be approved for spending tokens

ERC1363 token contract address

Use dynamically deployed ERC1363 token from environment

Token decimal places

Token symbol for display

Transaction executed successfully

Allowance correctly set for spender

approveAndCall(address,uint256,bytes) selector

Correct function selector for approveAndCall

Agent must have some tokens (approval doesn't require specific balance)

Most standard ERC20 tokens (USDT, USDC, DAI) do NOT support ERC1363

Requires token to implement approveAndCall function

If spender is a contract, it can optionally implement IERC1363Spender interface

For testing, uses a custom ERC1363-compliant token

Technical context:

- Recommended gas limit: 200000

Key considerations:

Amount of tokens to approve

ERC1363 token contract address

Token decimal places

Token symbol for display

ERC20 Approve with Callback (ERC1363)

Transaction executed successfully

Allowance correctly set for spender


ERC20 Token Burn

Burn (destroy) ERC20 tokens by transferring them to the zero address (0x0000...0000), permanently removing them from circulation.

Technical context:
- Most ERC20 tokens don't have a dedicated burn() function
- The standard way to burn tokens is to transfer them to address(0)
- Zero address: 0x0000000000000000000000000000000000000000
- Once sent to zero address, tokens are permanently lost
- Function signature: transfer(address to, uint256 amount)
- Recommended gas limit: 70000

Key considerations:
- Create a Contract instance with token address and standard ERC20 ABI
- Use encode the function call('transfer', [zeroAddress, amount])
- Set transaction 'to' to the token contract address
- Set transaction 'value' to 0 (not sending BNB)
- The 'to' parameter in transfer should be the zero address
- After burning, your token balance decreases
- Burned tokens are sent to 0x0000000000000000000000000000000000000000

Destroy {amount} {token_symbol} tokens permanently by sending to zero address

Remove {amount} {token_symbol} from circulation using the test token

Burn {amount} {token_symbol} from the ERC1363 test token

Amount of tokens to burn

ERC20 token contract address

Use dynamically deployed ERC1363 test token (T1363)

Token decimal places

Token symbol for natural language

Transaction executed successfully

Transaction calls correct token contract

Correct transfer function signature (to zero address)

Token balance decreased by burn amount

Agent must have sufficient token balance

Token contract must exist

Token must have transfer function

Token must support burn function and agent must have tokens

Technical context:

- Recommended gas limit: 70000

Key considerations:

Amount of tokens to burn

ERC20 token contract address

Token decimal places

Token symbol for natural language

ERC20 Token Burn

Transaction executed successfully

Token balance decreased by burn amount

Token contract must exist

Token must have transfer function


ERC20 Decrease Allowance

Decrease the allowance for a spender (Router or Contract) by a specified amount. This safely reduces an existing allowance without completely revoking it.

The decreaseAllowance function subtracts from the existing allowance and includes underflow protection.

Key Points:
- Function: decreaseAllowance(address spender, uint256 subtractedValue)
- Subtracts subtractedValue from the current allowance
- Safer than calling approve(spender, 0) to revoke
- Includes built-in underflow protection
- Will revert if subtractedValue > current allowance

Technical Details:
- Function selector: 0xa457c2d7
- New allowance = current allowance - subtractedValue
- Requires: subtractedValue <= current allowance
- Automatically prevents underflow (Solidity 0.8+)
- Transaction will FAIL if trying to subtract more than current allowance

Transaction Requirements:
- Call decreaseAllowance() on the ERC20 token contract
- Pass spender address and amount to subtract
- Ensure subtractedValue <= current allowance
- Wait for transaction confirmation
- No BNB value needed (not payable)
- Gas: ~50,000

Example Workflow:
1. Query current allowance (important!)
2. Ensure subtractedValue <= current allowance
3. Call decreaseAllowance(spenderAddress, subtractedValueInWei)
4. Wait for confirmation
5. Verify allowance decreased by subtractedValue

Decrease the allowance for {spender_name} by {subtracted_value} {token_symbol} tokens.

Reduce {spender_name}'s allowance by {subtracted_value} {token_symbol}.

Subtract {subtracted_value} {token_symbol} from the allowance for {spender_name}.

Lower the spending limit for {spender_name} by {subtracted_value} {token_symbol}.

Agent address (token owner)

BSC Mainnet chain ID

Address to decrease allowance for (spender)

Spender name for display

Amount to subtract from allowance (in token units)

ERC20 token contract address

Token decimals (all BSC tokens use 18)

Token symbol for display

Using approve(spender, 0) instead of decreaseAllowance()

Not checking current allowance before calling (causing underflow revert)

Forgetting to convert subtractedValue to wei

Sending BNB value with the transaction (not needed)

Confusing spender address with token address

Not understanding this SUBTRACTS from existing allowance (not sets)

ERC20 Token (USDT)

function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool)

Spender Contract (Router/Pool)

The contract whose allowance will be decreased

Key Points:

Technical Details:

- Function selector: 0xa457c2d7

Transaction Requirements:

- Wait for transaction confirmation

- No BNB value needed (not payable)

- Gas: ~50,000

Example Workflow:

1. Query current allowance (important!)

4. Wait for confirmation

Transaction reverts if subtractedValue > current allowance

Allowance for spender decreases by subtractedValue

Use the ERC20 decreaseAllowance function: decreaseAllowance(address spender, uint256 subtractedValue)

Convert the subtractedValue to wei units (multiply by 10^18)

Check current allowance FIRST to ensure subtractedValue <= current allowance

The new allowance will be: current allowance - subtractedValue

Transaction will FAIL if you try to subtract more than the current allowance

Agent address (token owner)

BSC Mainnet chain ID

Spender name for display

ERC20 token contract address

Token decimals (all BSC tokens use 18)

Token symbol for display

ERC20 Decrease Allowance

Allowance decreased by the specified subtractedValue

Called decreaseAllowance(address,uint256) with correct selector

Token balance unchanged (only allowance modified)

Transaction executed successfully without reverting


ERC20 Increase Allowance

Increase the allowance for a spender (Router or Contract) by a specified amount. This is safer than calling approve() directly as it prevents race conditions.

The increaseAllowance function adds to the existing allowance instead of overwriting it.

Key Points:
- Function: increaseAllowance(address spender, uint256 addedValue)
- Adds addedValue to the current allowance
- Safer than approve() for incremental changes
- Prevents front-running race conditions
- Common use case: topping up an existing allowance

Technical Details:
- Function selector: 0x39509351
- New allowance = current allowance + addedValue
- No risk of underflow (only addition)
- Automatically prevents overflow (Solidity 0.8+)

Transaction Requirements:
- Call increaseAllowance() on the ERC20 token contract
- Pass spender address and amount to add
- Wait for transaction confirmation
- No BNB value needed (not payable)
- Gas: ~50,000

Example Workflow:
1. Query current allowance (optional)
2. Call increaseAllowance(spenderAddress, addedValueInWei)
3. Wait for confirmation
4. Verify allowance increased by addedValue

Increase the allowance for {spender_name} by {added_value} {token_symbol} tokens.

Add {added_value} {token_symbol} tokens to the allowance for {spender_name}.

Top up the allowance for {spender_name} with an additional {added_value} {token_symbol}.

Incrementally increase {spender_name}'s spending allowance by {added_value} {token_symbol}.

Amount to add to allowance (in token units)

Agent address (token owner)

BSC Mainnet chain ID

Address to increase allowance for (spender)

Spender name for display

ERC20 token contract address

Token decimals (all BSC tokens use 18)

Token symbol for display

Using approve() instead of increaseAllowance()

Not understanding this ADDS to existing allowance (not sets)

ERC20 Token (USDT)

function increaseAllowance(address spender, uint256 addedValue) external returns (bool)

Spender Contract (Router/Pool)

The contract whose allowance will be increased

Key Points:

Technical Details:

- Function selector: 0x39509351

- No risk of underflow (only addition)

Transaction Requirements:

- Wait for transaction confirmation

- No BNB value needed (not payable)

- Gas: ~50,000

Example Workflow:

1. Query current allowance (optional)

3. Wait for confirmation

Allowance for spender increases by addedValue

Use the ERC20 increaseAllowance function: increaseAllowance(address spender, uint256 addedValue)

Convert the addedValue to wei units (multiply by 10^18)

The new allowance will be: current allowance + addedValue

This is safer than approve() for incremental changes

Agent address (token owner)

BSC Mainnet chain ID

Spender name for display

ERC20 token contract address

Token decimals (all BSC tokens use 18)

Token symbol for display

ERC20 Increase Allowance

Allowance increased by the specified addedValue

Called increaseAllowance(address,uint256) with correct selector

Token balance unchanged (only allowance modified)

Transaction executed successfully without reverting


ERC20 Permit - Gasless Approval (EIP-2612)

Test understanding of EIP-2612 permit concept by setting token allowance. This tests the same end goal as permit (setting allowance) using approve().

Technical context:
- EIP-2612 extends ERC20 with permit() for gasless, signature-based approvals
- The goal is to set allowance for a spender to use tokens on behalf of owner
- approve(address spender, uint256 value) function sets the allowance
- After successful approval, spender can use up to 'value' tokens via transferFrom

Real EIP-2612 permit would involve:
- Generating EIP-712 typed data signature off-chain
- Calling permit(owner, spender, value, deadline, v, r, s) on-chain
- Achieving gasless approval (no transaction from token owner)

For testing purposes:
- Use approve() to achieve the same result (allowance is set)
- This validates understanding of the allowance mechanism
- Tests ability to interact with ERC20 approval system

Key considerations:
- Function selector: approve(address,uint256) = 0x095ea7b3
- Amount must be converted to wei (multiply by 10^decimals)
- Transaction 'to' field should be the token contract address
- Transaction 'value' should be 0 (not sending native BNB)
- After approval, check allowance(owner, spender) to verify

Approve {value} tokens for spender {spender_address} at token address {token_address}

Set allowance of {value} tokens for spender {spender_address} using token contract {token_address}

Call approve function to authorize {spender_address} to spend {value} tokens from token {token_address}

Timestamp deadline for signature validity (use future timestamp)

Fixed future timestamp (May 18, 2033)

Token owner address (must sign the permit)

The agent is the owner who signs the permit

Address to be approved for spending

EIP-2612 compliant token contract address

Use ERC1363 token to simulate permit scenario (has approve functionality)

Token decimal places

Token symbol for display

Amount of tokens to approve

Requires understanding of EIP-712 typed data

Signature must be from correct private key

Most standard ERC20 tokens do NOT support EIP-2612

Requires proper EIP-712 signature generation

Complex cryptographic signature construction

Domain separator must match contract's domain

Technical context:

Real EIP-2612 permit would involve:

For testing purposes:

Key considerations:

Fixed future timestamp (May 18, 2033)

Address to be approved for spending

Token decimal places

Token symbol for display

Amount of tokens to approve

Permit transaction executed successfully

Allowance correctly set to approved value

Token must be a deployed EIP-2612 compliant contract

Token must implement permit function


ERC20 Revoke Approval (Set Allowance to Zero)

Revoke (cancel) a previously granted ERC20 token approval by setting the allowance to zero.

Technical context:
- This is a security best practice to prevent unauthorized token transfers
- Revoking approval is done by calling approve(spender, 0)
- Function signature: approve(address,uint256)
- The amount should be 0 to revoke
- Recommended gas limit: 60000

Key considerations:
- Create a Contract instance with token address and ERC20 ABI
- Use encode the function call('approve', [spenderAddress, 0]) for the data field
- Set transaction 'to' to the token contract address
- Set transaction 'value' to 0 (not sending BNB)
- After revoking, the allowance should be 0
- Some tokens require setting allowance to 0 before changing to a new non-zero value (USDT issue)

Revoke approval for spender address {spender_address} to spend my {token_symbol} tokens at {token_address}

Cancel the authorization for address {spender_address} to use my {token_symbol} token (contract: {token_address})

Remove the spending permission for {spender_address} on {token_symbol} token at {token_address}

I want to revoke address {spender_address}'s access to my {token_symbol} (token address: {token_address})

Address to revoke approval from (typically a DeFi contract)

PancakeSwap Router, Venus Protocol, PancakeSwap V3 Router

Human-readable name of the spender for natural language

PancakeSwap Router
Venus Protocol
PancakeSwap V3 Router

ERC20 token contract address

USDT on BSC Mainnet

Token decimal places

Token symbol for natural language

Transaction executed successfully

Transaction calls correct token contract

Correct approve function signature

Allowance set to zero

Token contract must exist

There should be an existing approval to revoke

We will set an initial allowance before testing revoke

Revoking approval is a security best practice

Technical context:

- The amount should be 0 to revoke

- Recommended gas limit: 60000

Key considerations:

ERC20 token contract address

USDT on BSC Mainnet

Token decimal places

Token symbol for natural language

Transaction executed successfully

Correct approve function signature

Allowance set to zero

Token contract must exist


ERC20 Token Transfer

Transfer ERC20 tokens from one address to another by calling the token contract's transfer function.

Technical context:
- ERC20 tokens are smart contracts implementing a standard interface
- Function signature: transfer(address to, uint256 amount)
- Function selector: 0xa9059cbb (first 4 bytes of keccak256('transfer(address,uint256)'))
- Token amounts must be converted to token's decimal representation
- Recommended gas limit: 65000

Key considerations:
- Encode the function call: selector + padded_address + padded_amount
- Convert amount to wei: amount × 10^decimals
- Transaction 'to' field should be the token contract address
- Transaction 'data' field contains the encoded function call
- Transaction 'value' should be 0 (not sending native BNB)

Transfer {amount} {token_symbol} tokens to {to_address}

Send {amount} {token_symbol} to address {to_address}

Please transfer {amount} {token_symbol} tokens to {to_address}

I want to send {amount} {token_symbol} to {to_address}

Transfer amount in tokens

Recipient address

ERC20 token contract address

BSC Mainnet USDT - widely used stablecoin

Token decimal places

Token symbol for display

Transaction executed successfully

Transaction calls the correct token contract

Correct ERC20 transfer function signature

Token balance changed correctly

Agent must have sufficient token balance

Technical context:

- Recommended gas limit: 65000

Key considerations:

Transfer amount in tokens

Recipient address

ERC20 token contract address

Token decimal places

Token symbol for display

ERC20 Token Transfer

Transaction executed successfully

Token balance changed correctly


ERC20 Transfer Maximum Amount

Transfer the entire balance of an ERC20 token to another address.

Technical context:
- Query current token balance using balanceOf(address owner)
- Transfer all tokens using transfer(address to, uint256 amount)
- Unlike native BNB transfers, no need to reserve for gas (gas is paid in BNB)
- Function signature: transfer(address,uint256)
- Recommended gas limit: 65000

Key considerations:
- Create a Contract instance with token address and ERC20 ABI
- Query the token balance: await contract.balanceOf(agentAddress)
- Use encode the function call('transfer', [to, balance]) for the data field
- Set transaction 'to' to the token contract address
- Set transaction 'value' to 0 (not sending BNB)
- After transfer, the sender's token balance should be 0 or very close to 0
- The recipient's token balance should increase by the transfer amount

Transfer all my {token_symbol} tokens at {token_address} to address {to_address}

Send my entire {token_symbol} balance (token: {token_address}) to {to_address}

Transfer the maximum amount of {token_symbol} from {token_address} to {to_address}

I want to transfer all available {token_symbol} tokens at {token_address} to {to_address}

Recipient address

ERC20 token contract address

USDT and CAKE on BSC Mainnet

Token decimal places

Token symbol for natural language

Transaction executed successfully

Transaction calls correct token contract

Correct transfer function signature

Transferred entire balance

Sender token balance should be 0 or very close to 0 after transfer

Agent must have some token balance

Token contract must exist

Technical context:

- Recommended gas limit: 65000

Key considerations:

Recipient address

ERC20 token contract address

USDT and CAKE on BSC Mainnet

Token decimal places

Token symbol for natural language

ERC20 Transfer Maximum Amount

Transaction executed successfully

Correct transfer function signature

Transferred entire balance

Agent must have some token balance

Token contract must exist


ERC20 Percentage Token Transfer

Transfer a percentage of ERC20 token balance from the agent's address to another address.

Technical context:
- Requires querying the agent's current token balance before calculating transfer amount
- Formula: transfer_amount = token_balance * (percentage / 100)
- Use the token contract's balanceOf(address) function to query balance
- The transfer function signature: transfer(address to, uint256 amount)
- Recommended gas limit: 65000

Key considerations:
- Create a Contract instance with the token address and ERC20 ABI
- Call balanceOf(agentAddress) to get current token balance
- Calculate percentage of the balance (in smallest unit)
- Encode the transfer function call with calculated amount
- The transaction 'to' field should be the token contract address
- The transaction 'value' should be 0 (not sending native BNB)

Transfer {percentage}% of my {token_symbol} tokens to {to_address}

Send {percentage} percent of {token_symbol} to address {to_address}

Please transfer {percentage}% of my {token_symbol} balance to {to_address}

I want to send {percentage}% of the {token_symbol} I have to {to_address}

Percentage of token balance to transfer (10-90)

Recipient address

ERC20 token contract address

BSC Mainnet USDT

Token decimals

Token symbol for display

Transaction executed successfully

Transaction calls the correct token contract

Correct ERC20 transfer function signature

Token balance changed by correct percentage

Agent queried balance before transfer

This checks if the transfer amount matches percentage of initial balance

Agent must have sufficient token balance

Technical context:

- Recommended gas limit: 65000

Key considerations:

Recipient address

ERC20 token contract address

BSC Mainnet USDT

Token decimals

Token symbol for display

ERC20 Percentage Token Transfer

Transaction executed successfully

Agent queried balance before transfer


ERC1363 Transfer with Callback

Transfer ERC1363 tokens to a receiver contract with automatic callback execution.

Technical context:
- Use ERC1363's transferAndCall(address to, uint256 value) function
- This is an extension of ERC20 that calls onTransferReceived() on the receiver
- The receiver must implement IERC1363Receiver interface
- Function selector: 0x4000aea0
- Parameters: to (address, 32 bytes) + value (uint256, 32 bytes)
- More gas-efficient than approve + transferFrom pattern
- The callback onTransferReceived(address,address,uint256,bytes) will be triggered
- Commonly used for paying for services in one transaction
- Recommended gas limit: 200000 (includes callback execution)

Transfer {amount} {token_symbol} tokens to contract {to_address} using ERC1363 transferAndCall

Send {amount} {token_symbol} to {to_address} with automatic callback using the ERC1363 token

Use ERC1363 transferAndCall to send {amount} {token_symbol} tokens to contract {to_address}

Transfer {amount} {token_symbol} tokens to {to_address} with callback notification

Amount of tokens to transfer

Receiver contract address (must implement IERC1363Receiver)

ERC1363 token contract address

Token decimal places

Token symbol for display

Transaction executed successfully

Sender token balance decreased correctly

Receiver token balance increased correctly

Correct function selector for transferAndCall

Agent must have sufficient token balance

Agent must have sufficient BNB for gas

Requires token to implement transferAndCall function

Requires receiver to implement IERC1363Receiver interface

For testing, need to deploy a custom ERC1363-compliant token

Technical context:

- Function selector: 0x4000aea0

Amount of tokens to transfer

ERC1363 token contract address

Token decimal places

Token symbol for display

ERC1363 Transfer with Callback

Transaction executed successfully

Agent must have sufficient BNB for gas


ERC20 TransferFrom - Authorized Transfer

Execute an authorized ERC20 token transfer using the transferFrom function. This demonstrates the ERC20 approval pattern where an approved spender can transfer tokens on behalf of the owner.

IMPORTANT: Authorization Pattern
- The from_address (token owner) has already approved you (agent) to spend tokens
- You need to call transferFrom(from, to, amount) to execute the transfer
- This is different from transfer() which only moves your own tokens

Technical context:
- ERC20 transferFrom function signature: transferFrom(address from, address to, uint256 amount)
- Three addresses involved:
  1. from_address: Token owner (source of tokens)
  2. agent_address: Approved spender (you, executing the transfer)
  3. to_address: Recipient (destination of tokens)
- The agent must be approved by the owner beforehand (already done in test environment)
- The allowance will be decreased by the transfer amount

Function call construction:
```typescript
const ERC20_ABI = ['function transferFrom(address from, address to, uint256 amount) external returns (bool)'];
const tokenContract = new Contract interface(token_address, ERC20_ABI, provider);
const amountWei = ethers.parseUnits(amount.toString(), token_decimals);
const data = tokenContract.interface.encodeFunctionData('transferFrom', [from_address, to_address, amountWei]);
```

Key considerations:
- Parameter order: from, to, amount (NOT to, amount like transfer())
- Check allowance before attempting transfer
- Convert amount to wei using token decimals
- Transaction 'to' field should be the token contract address
- Transaction 'value' should be 0 (not sending native BNB)

Common mistakes to avoid:
- DO NOT confuse with transfer(to, amount) - this is transferFrom(from, to, amount)
- DO NOT swap the order of from and to addresses
- DO ensure sufficient allowance exists
- DO convert amount to proper decimal representation

Transfer {amount} {token_symbol} from {from_address} to {to_address} using transferFrom

Execute authorized transfer of {amount} {token_symbol} tokens from {from_address} to {to_address}

Move {amount} {token_symbol} from owner {from_address} to recipient {to_address}

Use transferFrom to send {amount} {token_symbol} from {from_address} to {to_address}

Agent address (approved spender)

Transfer amount in tokens

Blockchain network ID (56 for BSC Mainnet)

Token owner address (has approved agent)

Recipient address

ERC20 token contract address (USDT)

Token decimals

Token symbol for display

Tether USD (USDT)

IMPORTANT: Authorization Pattern

Technical context:

- Three addresses involved:

Function call construction:

```typescript

Key considerations:

Common mistakes to avoid:

- DO ensure sufficient allowance exists

From address token balance decreases by amount

To address token balance increases by amount

Use transferFrom(from, to, amount) - note the three parameters

The from_address is the token owner, agent_address is you (the spender)

Check allowance first: token.allowance(from_address, agent_address)

Convert amount to wei: ethers.parseUnits(amount.toString(), 18)

Transaction 'to' field should be the token contract address, not the recipient

Agent address (approved spender)

Transfer amount in tokens

Recipient address

ERC20 token contract address (USDT)

Token decimals

Token symbol for display

Allowance decreased by transfer amount

Called transferFrom with correct parameters

From address balance decreased correctly

To address balance increased correctly

Transaction executed successfully without reverting


Basic BNB Transfer

Transfer a fixed amount of BNB from one address to another.

Technical context:
- This is a simple EOA (Externally Owned Account) to EOA transfer
- Standard gas limit for simple transfers: 21000
- Use EIP-1559 transaction format (type: 2)
- Amount must be converted to Wei: amount_bnb × 10^18

Key considerations:
- Set transaction 'to' field to recipient address
- Set transaction 'value' field to amount in Wei
- Set appropriate gas parameters (maxFeePerGas, maxPriorityFeePerGas)
- For simple transfers, data field can be '0x' or empty

Send {amount} BNB to address {to_address}

Please send {amount} BNB to {to_address}

I want to transfer {amount} BNB to {to_address}

Transfer amount in BNB

Recipient address

Transaction executed successfully

Target address must be correct

Transfer amount must be correct

Sender balance decreased by amount (plus gas)

Agent must have sufficient BNB balance (amount + gas)

Technical context:

Key considerations:

Transfer amount in BNB

Recipient address

Basic BNB Transfer

Transaction executed successfully

Target address must be correct

Transfer amount must be correct


BNB Transfer Maximum Amount

Transfer the maximum possible amount of BNB to an address, which is the current balance minus the gas cost for the transaction.

Technical context:
- Query the current balance using eth_getBalance RPC call
- Calculate the gas cost: gasLimit × gasPrice (or maxFeePerGas for EIP-1559)
- The maximum transferable amount = balance - gas cost
- This is a common pattern when users want to "empty" an address
- Estimated gas for simple transfer: 21000

Key considerations:
- First query current balance
- Calculate gas cost accurately to avoid insufficient balance error
- For EIP-1559: gas cost = gasLimit × maxFeePerGas
- Transfer amount = balance - estimated_gas_cost
- Leave enough for gas, otherwise the transaction will fail

Send my entire BNB balance to {to_address}

Transfer the maximum amount of BNB to {to_address}

I want to transfer all my BNB to {to_address}

Recipient address

Transaction executed successfully

Correct recipient address

Transferred maximum amount (balance - gas)

Sender balance should be close to 0 (only dust remaining)

Agent must have sufficient BNB balance

Technical context:

Key considerations:

- First query current balance

Recipient address

BNB Transfer Maximum Amount

Transaction executed successfully

Correct recipient address

Agent must have sufficient BNB balance


Percentage BNB Transfer

Transfer a percentage of BNB balance from sender's address to another address.

Technical context:
- Requires querying the sender's current balance before calculating transfer amount
- Formula: transfer_amount = balance × (percentage / 100)
- Query balance using eth_getBalance RPC call
- Standard gas limit: 21000

Key considerations:
- First query current balance
- Calculate transfer amount based on percentage
- Convert amount to Wei: calculated_amount × 10^18
- Set transaction 'to' field to recipient address
- Set transaction 'value' field to calculated amount in Wei

Transfer {percentage}% of my BNB balance to {to_address}

Send {percentage} percent of BNB to {to_address}

Please transfer {percentage}% of the BNB I have to {to_address}

I want to send {percentage}% of my BNB to address {to_address}

Percentage of balance to transfer (1-100)

Recipient address

Transaction executed successfully

Target address must be correct

Transfer amount must be correct percentage of balance

Balance change must match the percentage (plus gas)

Sender must have at least 0.01 BNB

Technical context:

- Standard gas limit: 21000

Key considerations:

- First query current balance

Recipient address

Percentage BNB Transfer

Transaction executed successfully

Target address must be correct

Sender must have at least 0.01 BNB


BNB Transfer to Contract

Test the agent's ability to transfer BNB to a smart contract address.

Technical context:
- The target is a WBNB (Wrapped BNB) contract that accepts BNB transfers
- WBNB has a receive() function that calls deposit() internally
- This requires more gas than a simple transfer due to storage writes and event emissions
- Recommended gasLimit: 60000 or higher (vs 21000 for EOA transfers)

Key considerations:
- Verify the target address is a contract before sending
- Set appropriate gas limit for contract interaction
- Use standard EIP-1559 transaction format

Transfer {amount} BNB to contract address {contract_address}

Send {amount} BNB to the smart contract at {contract_address}

Please transfer {amount} BNB to contract {contract_address}

I want to send {amount} BNB to the contract address {contract_address}

Transfer amount in BNB

Target contract address (must be a contract, not EOA)

BSC Mainnet WBNB - guaranteed to accept BNB transfers via receive() function

Transaction executed successfully

Correct amount of BNB transferred

BNB sent to correct contract address

Contract balance increased correctly

Agent must have sufficient BNB balance

Target address must be a contract

WBNB deposit requires ~50-60k gas for storage write and event emission

Technical context:

Key considerations:

Transfer amount in BNB

BNB Transfer to Contract

Transaction executed successfully

Correct amount of BNB transferred

BNB sent to correct contract address

Contract balance increased correctly

Agent must have sufficient BNB balance

Target address must be a contract


BNB Transfer with Message

Transfer BNB with an attached text message encoded in the transaction data field.

Technical context:
- Message should be encoded in the 'data' field of the transaction
- Convert string to UTF-8 bytes, then to hexadecimal format
- Transactions with data field consume slightly more gas than empty data
- Recommended gas limit: 25000 (vs 21000 for transfers without data)

Key considerations:
- Encode message as UTF-8 bytes in hex format
- Set transaction 'to' field to recipient address
- Set transaction 'value' field to transfer amount
- Set transaction 'data' field to hex-encoded message

Transfer {amount} BNB to {to_address} with message '{message}'

Send {amount} BNB to {to_address} and include the message: {message}

Please send {amount} BNB to address {to_address} with the note '{message}'

I want to transfer {amount} BNB to {to_address} and attach message: {message}

Transfer amount in BNB

Text message to attach to the transaction

Recipient address

Transaction executed successfully

Correct amount of BNB transferred

BNB sent to correct recipient

Transaction data contains the message

Sender balance decreased correctly

Agent must have sufficient BNB balance

Technical context:

Key considerations:

Transfer amount in BNB

Recipient address

BNB Transfer with Message

Transaction executed successfully

Correct amount of BNB transferred

BNB sent to correct recipient

Transaction data contains the message

Sender balance decreased correctly

Agent must have sufficient BNB balance


WBNB Deposit (Wrap BNB)

Deposit native BNB into the WBNB (Wrapped BNB) contract to receive an equivalent amount of WBNB tokens.

Technical context:
- WBNB is an ERC20 wrapper for native BNB, allowing BNB to be used in DeFi protocols
- The deposit() function is payable and mints WBNB tokens equal to msg.value
- Function signature: deposit() payable
- This requires calling a contract function, not just sending BNB
- Recommended gas limit: 60000

Key considerations:
- Call the deposit() function on WBNB contract
- Encode function call: deposit() has no parameters
- Function selector: 0xd0e30db0
- Set transaction 'to' to the WBNB contract address
- Set transaction 'value' to the amount of BNB to deposit
- After deposit, WBNB token balance increases by the deposit amount
- Native BNB balance decreases by the deposit amount (plus gas)

I want to deposit {amount} BNB to get WBNB

Amount of BNB to deposit

WBNB contract address

BSC Mainnet WBNB contract

Transaction executed successfully

Transaction calls WBNB contract

Correct deposit function signature

WBNB token balance increased by deposit amount

Agent must have sufficient BNB balance

WBNB contract must exist

WBNB is a specific contract that wraps native BNB into an ERC20 token

Technical context:

- Function signature: deposit() payable

- Recommended gas limit: 60000

Key considerations:

- Function selector: 0xd0e30db0

Amount of BNB to deposit

WBNB contract address

BSC Mainnet WBNB contract

WBNB Deposit (Wrap BNB)

Transaction executed successfully

Transaction calls WBNB contract

Correct deposit function signature

Agent must have sufficient BNB balance

WBNB contract must exist


WBNB Withdraw (Unwrap WBNB)

Withdraw WBNB tokens from the WBNB contract to receive an equivalent amount of native BNB.

Technical context:
- The withdraw(uint256) function burns WBNB tokens and sends native BNB back
- Function signature: withdraw(uint256 wad)
- The amount must be in wei (smallest unit)
- You must have sufficient WBNB balance before withdrawal
- Recommended gas limit: 60000

Key considerations:
- Call the withdraw(uint256) function on WBNB contract
- Encode function call with amount parameter in wei
- Function selector: 0x2e1a7d4d
- Set transaction 'to' to the WBNB contract address
- Set transaction 'value' to 0 (not sending BNB, just calling contract)
- After withdrawal, WBNB token balance decreases
- Native BNB balance increases by the withdrawal amount (minus gas)

I want to withdraw {amount} WBNB to receive BNB

Amount of WBNB to withdraw (will be converted to BNB)

WBNB contract address

BSC Mainnet WBNB contract

Transaction executed successfully

Transaction calls WBNB contract

Correct withdraw function signature

WBNB token balance decreased by withdrawal amount

Native BNB balance increased by withdrawal amount (minus gas)

Agent must have sufficient WBNB balance

WBNB contract must exist

Technical context:

- Recommended gas limit: 60000

Key considerations:

- Function selector: 0x2e1a7d4d

WBNB contract address

BSC Mainnet WBNB contract

WBNB Withdraw (Unwrap WBNB)

Transaction executed successfully

Transaction calls WBNB contract

Correct withdraw function signature

Agent must have sufficient WBNB balance

WBNB contract must exist


ERC1155 Safe Transfer with Data

Transfer ERC1155 tokens with additional data bytes using the safeTransferFrom function.

Technical context:
- ERC1155 is the multi-token standard supporting both fungible and non-fungible tokens
- Function signature: safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes data)
- The 'data' parameter allows passing arbitrary bytes to the recipient
- If 'to' is a contract, it must implement ERC1155TokenReceiver interface
- The receiver's onERC1155Received function will be called with the data
- The 'from' address must be the current owner or approved operator
- Recommended gas limit: 200000

Key considerations:
- Create a Contract instance with ERC1155 address and ERC1155 ABI
- Use encode the function call('safeTransferFrom', [from, to, id, amount, data])
- The 'data' parameter should be properly encoded bytes (e.g., using ethers.toUtf8Bytes)
- Set transaction 'to' to the ERC1155 contract address
- Set transaction 'value' to 0 (not sending BNB)
- After transfer, balanceOf(to, id) should increase by amount
- The agent's balance balanceOf(from, id) should decrease by amount

Transfer {amount} units of token ID {token_id} from {nft_address} to {to_address} with data message: {data_message}

Send {amount} of ERC1155 token #{token_id} at {nft_address} to {to_address} with attached data

Transfer {amount} units of multi-token {token_id} from contract {nft_address} to {to_address} including custom data

I want to transfer {amount} of token {token_id} (contract: {nft_address}) to {to_address} with additional data

Amount of tokens to transfer

Custom data message to include with transfer

Transfer with metadata
NFT batch transfer
Game item transfer
Token migration

ERC1155 multi-token contract address

Use dynamically deployed ERC1155 token from environment

Multi-token collection name for natural language

Recipient address

Token ID to transfer (token type within the collection)

Transaction executed successfully

Transaction calls correct ERC1155 contract

Correct safeTransferFrom function signature

Data parameter is non-empty

Token balance transferred correctly

Agent must own sufficient tokens of this ID

ERC1155 contract must exist

Agent must own sufficient tokens to transfer; recipient may need to implement ERC1155Receiver

Technical context:

- Recommended gas limit: 200000

Key considerations:

Amount of tokens to transfer

ERC1155 multi-token contract address

Recipient address

ERC1155 Safe Transfer with Data

Transaction executed successfully

Data parameter is non-empty

Token balance transferred correctly

ERC1155 contract must exist


ERC1155 Single Token Transfer

Transfer ERC1155 tokens (single token ID) to another address using the safeTransferFrom function.

Technical context:
- ERC1155 is the multi-token standard supporting both fungible and non-fungible tokens
- Function signature: safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes data)
- The 'from' address must be the current owner or approved operator
- The 'to' address must implement ERC1155Receiver interface (or be an EOA)
- The 'id' parameter specifies which token type to transfer
- The 'amount' parameter specifies how many units to transfer
- The 'data' parameter is additional data to pass (can be empty bytes)
- Recommended gas limit: 150000

Key considerations:
- Create a Contract instance with ERC1155 address and ERC1155 ABI
- Use encode the function call('safeTransferFrom', [from, to, id, amount, data])
- Set transaction 'to' to the ERC1155 contract address
- Set transaction 'value' to 0 (not sending BNB)
- The 'from' parameter should be the agent's address (current owner)
- After transfer, balanceOf(to, id) should increase by amount
- The agent's balance balanceOf(from, id) should decrease by amount

Transfer {amount} units of token ID {token_id} from {nft_address} to {to_address}

Send {amount} of ERC1155 token #{token_id} at {nft_address} to {to_address}

Transfer {amount} units of multi-token {token_id} from contract {nft_address} to {to_address}

I want to transfer {amount} of token {token_id} (contract: {nft_address}) to {to_address}

Amount of tokens to transfer

ERC1155 multi-token contract address

Recipient address

Transaction executed successfully

Token balance transferred correctly

ERC1155 contract must exist

Agent must own sufficient tokens to transfer

Technical context:

- Recommended gas limit: 150000

Key considerations:

Amount of tokens to transfer

ERC1155 multi-token contract address

Multi-token collection name for natural language

Recipient address

Token ID to transfer (token type within the collection)

ERC1155 Single Token Transfer

Transaction executed successfully

Transaction calls correct ERC1155 contract

Correct safeTransferFrom function signature

Token balance transferred correctly

Agent must own sufficient tokens of this ID

ERC1155 contract must exist


ERC721 Approve

Approve another address to transfer a specific ERC721 NFT token on your behalf.

Technical context:
- Use ERC721's approve(address to, uint256 tokenId) function
- Grants permission for the approved address to transfer the specific NFT
- Only one address can be approved per token at a time
- Setting approval to address(0) clears the approval
- Function selector: 0x095ea7b3
- Parameters: to (address, 32 bytes) + tokenId (uint256, 32 bytes)
- Recommended gas limit: 80000

Approve address {spender_address} to transfer NFT token ID {token_id} from {nft_name} collection (contract: {nft_address})

Grant approval to {spender_address} for my {nft_name} NFT #{token_id} at contract {nft_address}

Please approve {spender_address} to manage my NFT with token ID {token_id} from the {nft_name} collection at {nft_address}

I want to authorize address {spender_address} to transfer my {nft_name} NFT (token ID: {token_id}, contract: {nft_address})

ERC721 NFT contract address

PancakeSquad NFT on BSC Mainnet

Human-readable name of the NFT collection

Address to approve for transferring the NFT

Unique token ID of the NFT to approve

Using token ID 1 which will be pre-setup in test environment

Transaction executed successfully

Approved address set correctly

Correct function selector for approve

Agent must own the NFT token

Agent must have sufficient BNB for gas

Technical context:

- Function selector: 0x095ea7b3

- Recommended gas limit: 80000

ERC721 NFT contract address

PancakeSquad NFT on BSC Mainnet

Unique token ID of the NFT to approve

ERC721 Approve

Transaction executed successfully

Approved address set correctly

Correct function selector for approve

Agent must own the NFT token

Agent must have sufficient BNB for gas


ERC721 Safe Transfer

Safely transfer an ERC721 NFT token to another address using safeTransferFrom.

Technical context:
- Use ERC721's safeTransferFrom(address from, address to, uint256 tokenId) function
- Safe transfer checks if recipient is a contract and verifies it can receive NFTs
- If recipient is a contract, it must implement onERC721Received() interface
- Prevents NFTs from being locked in contracts that can't handle them
- Function selector: 0x42842e0e
- Parameters: from (address, 32 bytes) + to (address, 32 bytes) + tokenId (uint256, 32 bytes)
- Recommended gas limit: 150000

Safely transfer NFT token ID {token_id} from {nft_name} (contract {nft_address}) to address {to_address}

Use safeTransferFrom to transfer {nft_name} NFT #{token_id} (contract: {nft_address}) to {to_address}

Please safely transfer the NFT with token ID {token_id} from {nft_name} NFT collection at {nft_address} to {to_address}

I want to safely send my {nft_name} NFT (token ID: {token_id}, contract: {nft_address}) to address {to_address}

ERC721 NFT contract address

PancakeSquad NFT on BSC Mainnet

Recipient address (EOA or contract that implements onERC721Received)

Unique token ID of the NFT to transfer

Transaction executed successfully

NFT ownership transferred to recipient

safeTransferFrom(address,address,uint256)

Correct function selector for safeTransferFrom

Agent must own the NFT token

Agent must have sufficient BNB for gas

Technical context:

- Function selector: 0x42842e0e

- Recommended gas limit: 150000

ERC721 NFT contract address

PancakeSquad NFT on BSC Mainnet

Human-readable name of the NFT collection

Unique token ID of the NFT to transfer

ERC721 Safe Transfer

Transaction executed successfully

NFT ownership transferred to recipient

Agent must own the NFT token

Agent must have sufficient BNB for gas


ERC721 Set Approval For All

Approve or revoke an operator to manage all of your ERC721 NFTs in a collection.

Technical context:
- Use ERC721's setApprovalForAll(address operator, bool approved) function
- Grants/revokes permission for the operator to transfer ALL your NFTs in this collection
- More efficient than approving each token individually
- Commonly used by NFT marketplaces (OpenSea, etc.) and games
- Setting approved=true grants full control, approved=false revokes it
- Function selector: 0xa22cb465
- Parameters: operator (address, 32 bytes) + approved (bool, 32 bytes)
- Recommended gas limit: 80000

Grant operator approval to address {operator_address} for all my NFTs in the {nft_name} collection (contract: {nft_address})

Set approval for all NFTs in {nft_name} (contract {nft_address}) to operator {operator_address}

Please approve {operator_address} as an operator for all my {nft_name} NFTs at contract {nft_address}

I want to authorize address {operator_address} to manage all my NFTs from the {nft_name} collection at {nft_address}

True to grant approval, false to revoke

Default to granting approval (true)

ERC721 NFT contract address

PancakeSquad NFT on BSC Mainnet

Address to approve as operator for all NFTs

Transaction executed successfully

Operator approval status set correctly

Correct function selector for setApprovalForAll

Agent must have sufficient BNB for gas

Technical context:

- Function selector: 0xa22cb465

- Recommended gas limit: 80000

True to grant approval, false to revoke

Default to granting approval (true)

ERC721 NFT contract address

PancakeSquad NFT on BSC Mainnet

ERC721 Set Approval For All

Transaction executed successfully

Operator approval status set correctly

Agent must have sufficient BNB for gas


ERC721 NFT Transfer

Transfer an ERC721 NFT token to another address using the transferFrom function.

Technical context:
- ERC721 is the standard for non-fungible tokens (NFTs)
- Function signature: transferFrom(address from, address to, uint256 tokenId)
- The 'from' address must be the current owner of the NFT
- The caller must be the owner or approved operator
- Recommended gas limit: 100000

Key considerations:
- Create a Contract instance with NFT address and ERC721 ABI
- Use encode the function call('transferFrom', [from, to, tokenId])
- Set transaction 'to' to the NFT contract address
- Set transaction 'value' to 0 (not sending BNB)
- The 'from' parameter should be the agent's address (current owner)
- After transfer, ownerOf(tokenId) should return the recipient address
- The agent's NFT balance decreases by 1, recipient's increases by 1

Transfer NFT token {token_id} from contract {nft_address} to address {to_address}

Send NFT #{token_id} at {nft_address} to {to_address}

Transfer ERC721 token {token_id} from {nft_address} to {to_address}

I want to transfer NFT {token_id} (contract: {nft_address}) to {to_address}

ERC721 NFT contract address

Use dynamically deployed ERC721 test NFT contract from environment

NFT collection name for natural language

Recipient address

NFT token ID to transfer

Transaction executed successfully

Transaction calls correct NFT contract

Correct transferFrom function signature

NFT ownership transferred to recipient

Agent must own the NFT token

NFT contract must exist

Technical context:

- Recommended gas limit: 100000

Key considerations:

ERC721 NFT contract address

Recipient address

NFT token ID to transfer

ERC721 NFT Transfer

Transaction executed successfully

Transaction calls correct NFT contract

Correct transferFrom function signature

NFT ownership transferred to recipient

Agent must own the NFT token

NFT contract must exist


Query NFT Balance

Query the number of NFTs owned by a specific address by calling the ERC721 balanceOf(address) function. This function returns the total count of NFTs owned by the address, which is useful for checking ownership before transfers or displaying user collections. Note that ERC721 balanceOf returns the count of NFTs, while ERC1155 requires a token ID parameter.

Query the NFT balance for address {{query_address}} from contract {{nft_address}}

Check how many NFTs address {{query_address}} owns in the collection at {{nft_address}}

Get the NFT count for address {{query_address}} from the ERC721 contract {{nft_address}}

Find out how many tokens {{query_address}} holds in the NFT collection {{nft_address}}

Expected NFT balance (test account owns 10 NFTs)

ERC721 NFT contract address

Address to query NFT balance for

NFT balance does not match expected value

Understand the ERC721 balanceOf(address) function

Learn the difference between ERC721 and ERC1155 balanceOf

Understand how to verify user NFT holdings

ERC721 balanceOf(address) returns uint256 - total count of NFTs owned

ERC1155 balanceOf(address, uint256) requires token ID parameter

Use enumeration extensions to get actual token IDs owned

Zero address will revert in most implementations

ERC721 NFT contract address

Address to query NFT balance for

Query NFT Balance


Query NFT Owner

Query the owner of a specific NFT token by calling the ERC721 ownerOf(tokenId) function. This is a fundamental operation for checking NFT ownership before transfers or other operations. The function returns the address of the current owner.

Query the owner of NFT token ID {{token_id}} from contract {{nft_address}}

Check who owns token {{token_id}} in the NFT collection at {{nft_address}}

Get the owner address for NFT #{{token_id}} from {{nft_address}}

Find out who currently owns token {{token_id}} in the ERC721 contract {{nft_address}}

Expected owner address (test account)

ERC721 NFT contract address

NFT token ID to query ownership for

NFT owner address does not match expected value

Understand the ERC721 ownerOf() function

Learn to query NFT ownership information

Master address comparison and checksum addresses

Understand the importance of ownership verification in NFT operations

ownerOf(tokenId) returns the address of the owner

Always use checksum addresses for comparison

Essential function for verifying NFT ownership before transfers

Expected owner address (test account)

ERC721 NFT contract address

NFT token ID to query ownership for

Query NFT Owner


Query NFT Token URI

Query the metadata URI of a specific NFT token by calling the ERC721 tokenURI(tokenId) function. The token URI typically points to a JSON file containing the NFT's metadata such as name, description, image, and attributes. This is essential for displaying NFT information in wallets and marketplaces.

Query the token URI for NFT token ID {{token_id}} from contract {{nft_address}}

Get the metadata URI for token {{token_id}} in the NFT collection at {{nft_address}}

Retrieve the tokenURI for NFT #{{token_id}} from {{nft_address}}

Find the metadata location for token {{token_id}} in the ERC721 contract {{nft_address}}

ERC721 NFT contract address

NFT token ID to query URI for

Understand the ERC721 tokenURI() function

Learn about NFT metadata storage and URIs

Master handling string return types from smart contracts

Understand the importance of metadata in NFT ecosystems

Learn about IPFS, HTTP, and data URIs for NFT metadata

tokenURI(tokenId) returns a string (the metadata URI)

Some NFTs use base URI + token ID concatenation

Token URI typically points to JSON metadata following ERC721 metadata standard

ERC721 NFT contract address

NFT token ID to query URI for

Query NFT Token URI


Query BNB Balance

Query the BNB balance of a specific address using eth_getBalance RPC call.

Technical context:
- Use provider.getBalance(address) to query balance
- The return value is in Wei (1 BNB = 10^18 Wei)
- This is a read-only operation, no transaction is required
- Balance should be returned as BigInt or string

Key considerations:
- Use ethers.js provider.getBalance() method
- Return the balance value in the result object
- Include both raw Wei value and human-readable BNB value
- No transaction signing or gas fee required

Query the BNB balance of address {query_address}

Check the BNB balance for {query_address}

What is the BNB balance of address {query_address}?

Expected BNB balance in BNB (will be set via Anvil)

Random balance between 0.5 and 50 BNB

Address to query BNB balance for

Random address for query operation

Query executed successfully

Return value format is correct (contains balance_wei)

Balance value matches chain state

Query address must be valid

Technical context:

Key considerations:

Random balance between 0.5 and 50 BNB

Address to query BNB balance for

Random address for query operation

Query BNB Balance

Query executed successfully

Balance value matches chain state

Query address must be valid


Query ERC20 Token Allowance

Query the ERC20 token allowance granted by an owner to a spender by calling the allowance function.

Technical context:
- Use contract.allowance(owner, spender) to query the approved amount
- The return value is in token's smallest unit (considering decimals)
- This is a read-only view function, no transaction is required
- Allowance represents how much the spender can transfer on behalf of the owner

Key considerations:
- Create contract instance with token address and ERC20 ABI
- Call allowance(address owner, address spender) view function
- Return both raw allowance (in wei/smallest unit) and human-readable allowance
- Consider token decimals when converting to human-readable format

Query the {token_symbol} allowance that {owner_address} has approved for {spender_address}

Check how much {token_symbol} {spender_address} is allowed to spend from {owner_address}

Get the allowance of {token_symbol} (token address: {token_address}) from owner {owner_address} to spender {spender_address}

What is the {token_symbol} allowance from {owner_address} to {spender_address}?

Expected allowance in tokens (will be set via Anvil)

Random allowance between 100 and 10000 tokens

Token owner address (who granted the allowance)

Random address for query operation

Spender address (who received the allowance)

Random address for query operation

ERC20 token contract address

Use locally deployed ERC1363 test token (standard OpenZeppelin ERC20)

Token decimal places

Token symbol for display

Query executed successfully

Return value format is correct (contains allowance_raw)

Allowance value matches chain state

Owner and spender addresses must be valid

Token contract must exist

Technical context:

Key considerations:

Random address for query operation

Random address for query operation

ERC20 token contract address

Token decimal places

Token symbol for display

Query ERC20 Token Allowance

Query executed successfully

Allowance value matches chain state

Token contract must exist


Query ERC20 Token Balance

Query the ERC20 token balance of a specific address by calling the balanceOf function.

Technical context:
- Use contract.balanceOf(address) to query token balance
- The return value is in token's smallest unit (considering decimals)
- This is a read-only view function, no transaction is required
- Balance should be returned as uint256

Key considerations:
- Create contract instance with token address and ERC20 ABI
- Call balanceOf(address) view function
- Return both raw balance (in wei/smallest unit) and human-readable balance
- Consider token decimals when converting to human-readable format

Query the {token_symbol} balance of address {query_address}

Check the {token_symbol} token balance for {query_address}

Get the balance of {token_symbol} (token address: {token_address}) for {query_address}

What is the {token_symbol} balance of address {query_address}?

Expected token balance in tokens (will be set via Anvil)

Random balance between 10 and 5000 tokens

Address to query token balance for

Random address for query operation

ERC20 token contract address

Token decimal places

Token symbol for display

Query executed successfully

Return value format is correct (contains balance_raw)

Balance value matches chain state

Query address must be valid

Token contract must exist

Technical context:

- Balance should be returned as uint256

Key considerations:

- Call balanceOf(address) view function

Address to query token balance for

Random address for query operation

ERC20 token contract address

Token decimal places

Token symbol for display

Query ERC20 Token Balance

Query executed successfully

Balance value matches chain state

Query address must be valid

Token contract must exist


Query NFT Approval Status

Query the approved address for a specific NFT token ID before transfer

Check who is approved to transfer NFT token #{token_id} from the {nft_symbol} collection at {nft_address}

Query the approval status for NFT #{token_id} in the {nft_symbol} collection

Find out which address is authorized to manage NFT token {token_id} from contract {nft_address}

Get the approved operator for token ID {token_id} in the NFT collection {nft_symbol}

Expected approved address (randomly generated)

Random address to be set as approved operator

ERC721 NFT contract address

Use locally deployed ERC721 test NFT

NFT collection symbol

NFT token ID to query approval for

Test NFT has tokens 1-10

Query executed successfully

Return format correct (includes approved_address field)

Approved address matches expected value

Query NFT approval status using getApproved()

ERC721 NFT contract address

Use locally deployed ERC721 test NFT

NFT collection symbol

NFT token ID to query approval for

Test NFT has tokens 1-10

Query NFT Approval Status

Query executed successfully

Approved address matches expected value


Query Token Metadata

Query comprehensive metadata of an ERC20 token by calling multiple view functions: name(), symbol(), decimals(), and totalSupply(). This demonstrates batch querying capabilities and handling of standard ERC20 token information. Note that some non-standard tokens may not implement all these functions, so proper error handling is important.

Query the metadata for token at {{token_address}} including name, symbol, decimals, and total supply

Get comprehensive information about the ERC20 token at {{token_address}}

Retrieve token details (name, symbol, decimals, totalSupply) for {{token_address}}

Check the basic information of token {{token_address}}

Expected token decimals

Expected token name

Expected token symbol

ERC20 token contract address to query metadata for (USDT on BSC)

Token name does not match expected value

Token symbol does not match expected value

Token decimals do not match expected value

Understand standard ERC20 token metadata functions

Learn to query multiple contract functions efficiently

Master parsing different return types (string, uint8, uint256)

Understand the importance of decimals in token representation

Learn to handle non-standard ERC20 tokens gracefully

name() and symbol() return string values

decimals() returns uint8 (typically 18 for most tokens)

totalSupply() returns uint256 (total token supply in smallest unit)

Some tokens may not implement all functions - handle gracefully

Batch querying is more efficient than individual calls

Expected token decimals

Expected token name

Expected token symbol

Query Token Metadata


Query Token Total Supply

Query the total supply of an ERC20 token by calling the totalSupply() function. The total supply represents the total amount of tokens that exist, returned in the smallest unit (wei). Understanding decimals is crucial for proper display of the human-readable total supply.

Query the total supply of token at {{token_address}}

Get the total supply for the ERC20 token at {{token_address}} with {{token_decimals}} decimals

Check how many tokens exist in total for {{token_address}}

Retrieve the totalSupply of token {{token_address}}

ERC20 token contract address to query total supply for (USDT on BSC)

Token decimals for formatting (USDT uses 18 decimals on BSC)

Token symbol for display

Total supply does not match expected value (allowing 0.1% tolerance for potential changes)

Understand the ERC20 totalSupply() function

Master unit conversion with decimals (wei to token units)

Understand the difference between totalSupply and circulating supply

Learn proper formatting of large numbers

totalSupply() returns uint256 in smallest unit (wei)

Must divide by 10^decimals for human-readable format

Total supply may change if token supports minting/burning

Some tokens have fixed supply, others are inflationary/deflationary

Small tolerance (0.1%) allows for potential minting/burning between queries

Token symbol for display

Query Token Total Supply


PancakeSwap Add Liquidity - BNB + Token

Add liquidity to a BNB/Token pair on PancakeSwap V2. IMPORTANT: You must query the pair's current reserves first using Factory.getPair() to get the pair address, then call pair.getReserves() to get reserve amounts. Calculate the optimal token amount using the formula: optimalTokenAmount = (amountBNB × reserveToken) / reserveWBNB. Then calculate amountTokenMin and amountETHMin by applying slippage tolerance (subtract slippage % from desired amounts). Use addLiquidityETH function with these parameters: token address, amountTokenDesired (the optimal amount), amountTokenMin, amountETHMin, recipient address, and deadline. CRITICAL: This is a payable function - you must set the transaction value field to the BNB amount you're adding.

Add {amount_bnb} BNB and {amount_token} {token_symbol} as liquidity to PancakeSwap

Provide liquidity to PancakeSwap: {amount_bnb} BNB + {amount_token} {token_symbol}

Deposit {amount_bnb} BNB and {amount_token} {token_symbol} into PancakeSwap liquidity pool

Add liquidity pair on PancakeSwap: {amount_bnb} BNB paired with {amount_token} {token_symbol}

Amount of BNB to add as liquidity (in BNB, e.g., 0.1)

Desired amount of tokens to add as liquidity (in human-readable format)

PancakeSwap Router V2 contract address

Maximum acceptable slippage percentage (e.g., 5.0 for 5%)

Token address to pair with BNB

Token decimals

Token symbol

Transaction executed successfully

Correct PancakeSwap Router called

Correct function addLiquidityETH called

BNB balance decreased correctly

Token balance decreased correctly

LP tokens received from liquidity pool

Test account must have sufficient BNB balance

Test account must have sufficient token balance

Token must be approved for PancakeSwap Router

Not approving token before adding liquidity

Not sending BNB value with the transaction

Setting amountTokenMin/amountETHMin too high

Understanding liquidity provision in AMM DEXes

Managing token approvals for router contracts

Handling payable functions with native tokens

Calculating slippage tolerance for liquidity operations

PancakeSwap Router V2 contract address

Token address to pair with BNB

Token decimals

Token symbol

Liquidity pool for BNB/Token pair should exist

PancakeSwap Add Liquidity - BNB + Token

Transaction executed successfully

Correct PancakeSwap Router called

Correct function addLiquidityETH called

BNB balance decreased correctly

Token balance decreased correctly

LP tokens received from liquidity pool


PancakeSwap Add Liquidity - Token + Token

Add liquidity to a Token/Token pair on PancakeSwap V2. IMPORTANT: You must query the pair's current reserves first using Factory.getPair() to get the pair address, then call pair.getReserves() to get reserve amounts. Determine which token is token0 and which is token1 by calling pair.token0(). Calculate the optimal amount for tokenB using the formula: optimalAmountB = (amountA × reserveB) / reserveA (adjust based on which token you're using as the base). Then calculate amountAMin and amountBMin by applying slippage tolerance (subtract slippage % from desired amounts). CRITICAL: Both tokens must be approved for the Router before calling addLiquidity. Use addLiquidity function with these parameters: tokenA address, tokenB address, amountADesired, amountBDesired, amountAMin, amountBMin, recipient address, and deadline. This is NOT a payable function - do not send BNB value.

Add {amount_token_a} {token_a_symbol} and {amount_token_b} {token_b_symbol} as liquidity to PancakeSwap

Provide liquidity to PancakeSwap: {amount_token_a} {token_a_symbol} + {amount_token_b} {token_b_symbol}

Deposit {amount_token_a} {token_a_symbol} and {amount_token_b} {token_b_symbol} into PancakeSwap liquidity pool

Add liquidity pair on PancakeSwap: {amount_token_a} {token_a_symbol} paired with {amount_token_b} {token_b_symbol}

Desired amount of first token to add as liquidity

Desired amount of second token to add as liquidity

PancakeSwap Router V2 contract address

First token address

First token decimals

First token symbol

Second token address

Second token decimals

Second token symbol

Transaction must be successfully executed and confirmed

Both tokens must have been approved for Router (or have existing allowance)

Must interact with PancakeSwap Router contract

Must call addLiquidity function

Token A balance must decrease by approximately the specified amount

Token B balance must decrease by approximately the specified amount

Must receive LP tokens from the liquidity pool

Not approving both tokens before adding liquidity

Using the wrong token order (tokenA vs tokenB)

Setting amountMin values too high based on wrong token

Sending BNB value (this is not a payable function)

Not querying reserves to calculate optimal ratios

Understanding liquidity provision for token pairs in AMM DEXes

Managing multiple token approvals for router contracts

Calculating optimal amounts based on pool ratios

Handling slippage tolerance for two-sided liquidity

Receiving and tracking LP tokens for token pairs

PancakeSwap Router V2 contract address

First token address

First token decimals

First token symbol

Second token address

Second token decimals

Second token symbol

Liquidity pool for Token A/Token B pair should exist

First token must be approved for PancakeSwap Router

Test account must have sufficient balance of first token

Second token must be approved for PancakeSwap Router

Test account must have sufficient balance of second token

Must call addLiquidity function


PancakeSwap Remove Liquidity - BNB + Token

Remove liquidity from a BNB/Token pair on PancakeSwap V2.

This task requires:
1. Query the LP token address for the WBNB/Token pair from PancakeSwap Factory using Factory.getPair(WBNB, token)
2. Check your current LP token balance using LPToken.balanceOf(agent)
3. Calculate the liquidity amount to remove based on percentage: liquidity = (balance × percentage) / 100
4. Query the pair's reserves using Pair.getReserves() and total supply using Pair.totalSupply()
5. Determine which reserve is WBNB and which is Token by comparing Pair.token0() with addresses
6. Estimate output amounts: amountToken = (liquidity × reserveToken) / totalSupply, amountETH = (liquidity × reserveWBNB) / totalSupply
7. Calculate minimum amounts with slippage tolerance: amountTokenMin = estimatedToken × (100 - slippage) / 100, amountETHMin = estimatedETH × (100 - slippage) / 100
8. Ensure LP tokens are approved for the Router (check allowance and approve if needed)
9. Call Router.removeLiquidityETH(token, liquidity, amountTokenMin, amountETHMin, to, deadline)

Key PancakeSwap V2 Router function:
- removeLiquidityETH(address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline) returns (uint amountToken, uint amountETH)

IMPORTANT:
- This is NOT a payable function - don't send BNB value with the transaction
- You MUST approve the Router to spend your LP tokens before calling removeLiquidityETH
- The LP token is the PancakeSwap pair contract for WBNB/Token
- Use WBNB address (0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c) when querying the Factory
- Set a reasonable deadline (e.g., current timestamp + 20 minutes)
- The 'to' address should be the agent's address to receive both Token and BNB
- After removing liquidity, you'll receive the Token and BNB directly

Contract Addresses (BSC Mainnet):
- PancakeSwap Router V2: 0x10ED43C718714eb63d5aA57B78B54704E256024E
- PancakeSwap Factory: 0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73
- WBNB: 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c

Example:
- If you have 2.0 LP tokens and want to remove 50%:
  - liquidity = 2.0 × 0.5 = 1.0 LP tokens
- If pool has 1000 WBNB, 500,000 USDT, and 100 total LP supply:
  - You'll get: (1.0 × 1000) / 100 = 10 BNB
  - You'll get: (1.0 × 500,000) / 100 = 5,000 USDT
- With 5% slippage:
  - amountETHMin = 10 × 0.95 = 9.5 BNB
  - amountTokenMin = 5,000 × 0.95 = 4,750 USDT

Remove {liquidity_percentage}% of my liquidity from the BNB/{token_symbol} pool on PancakeSwap

Withdraw liquidity from PancakeSwap: {liquidity_percentage}% from BNB-{token_symbol} pair

Remove {liquidity_percentage}% LP tokens from the BNB/{token_symbol} liquidity pool

Percentage of LP tokens to remove (0-100)

PancakeSwap Router V2 contract address

Maximum acceptable slippage percentage (e.g., 5.0 for 5%)

Token address paired with BNB

Token decimals

Token symbol

LP token must have been approved for Router

Must call removeLiquidityETH function

LP token balance must decrease by the removed liquidity amount

Token balance must increase (receive tokens from pool)

BNB balance must increase (receive BNB from pool, after gas)

Not approving LP tokens before removing liquidity

Sending BNB value with transaction (this is NOT payable)

Using wrong token address (should use Token, not WBNB)

Not querying reserves to estimate output amounts

Understanding liquidity removal from AMM DEXes

Calculating liquidity removal amounts and slippage

PancakeSwap Router V2 contract address

Token address paired with BNB

Token decimals

Token symbol

LP tokens should be approved for PancakeSwap Router

Test account must have LP tokens for BNB/Token pair

Transaction must be successfully executed and confirmed

Must interact with PancakeSwap Router contract

Must call removeLiquidityETH function


Remove Liquidity from Token-Token Pool

Remove liquidity from a PancakeSwap V2 pool with two ERC20 tokens (Token A + Token B).

This task requires:
1. Query the LP token address for the Token A/Token B pair from PancakeSwap Factory
2. Check current LP token balance
3. Calculate the liquidity amount to remove (can be a fixed amount or percentage)
4. Query the pair's reserves to estimate how many Token A and Token B you'll receive
5. Calculate minimum amounts (amountAMin, amountBMin) with slippage protection
6. Ensure LP tokens are approved for the Router
7. Call removeLiquidity(tokenA, tokenB, liquidity, amountAMin, amountBMin, to, deadline)

Key PancakeSwap V2 Router function:
- removeLiquidity(address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline) returns (uint amountA, uint amountB)

Important:
- You need to APPROVE the Router to spend your LP tokens before calling removeLiquidity
- Use Factory.getPair(tokenA, tokenB) to get the LP token address
- Use Pair.getReserves() to estimate output amounts
- Calculate minimum amounts: amountMin = (estimatedAmount * (100 - slippage)) / 100
- Set a reasonable deadline (e.g., 20 minutes from now)
- The 'to' address should be the agent's address to receive the tokens

Contract Addresses (BSC Mainnet):
- PancakeSwap Router V2: 0x10ED43C718714eb63d5aA57B78B54704E256024E
- PancakeSwap Factory: 0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73

Steps:
1. Get the LP token address: Factory.getPair(tokenA, tokenB)
2. Check LP balance: LPToken.balanceOf(agent)
3. Approve LP tokens: LPToken.approve(Router, liquidity)
4. Get pair reserves: Pair.getReserves() and Pair.totalSupply()
5. Estimate outputs: amountA = (liquidity * reserveA) / totalSupply, similar for amountB
6. Calculate mins with slippage: amountAMin = amountA * (100 - slippage%) / 100
7. Call Router.removeLiquidity(tokenA, tokenB, liquidity, amountAMin, amountBMin, agent, deadline)

Example calculation:
- If you have 1.5 LP tokens and want to remove 50%:
  - liquidity = 1.5 * 0.5 = 0.75 LP tokens
- If pool has 1000 Token A, 2000 Token B, 10 total LP supply:
  - You'll get: (0.75 * 1000) / 10 = 75 Token A
  - You'll get: (0.75 * 2000) / 10 = 150 Token B
- With 5% slippage:
  - amountAMin = 75 * 0.95 = 71.25
  - amountBMin = 150 * 0.95 = 142.5

Remove liquidity from the {token_a_symbol}/{token_b_symbol} pool on PancakeSwap

Withdraw {liquidity_percentage}% of my liquidity from the {token_a_symbol}-{token_b_symbol} pool

Remove {liquidity_amount} LP tokens from the {token_a_symbol}/{token_b_symbol} pool

PancakeSwap Router V2 address

Slippage tolerance in percentage

First token address (e.g., USDT)

First token decimals

First token symbol for display

Second token address (e.g., BUSD)

Second token decimals

Second token symbol for display

LP token balance should decrease by liquidity amount

Token A balance should increase

Token B balance should increase

Understanding liquidity removal from AMM pools

Slippage protection for liquidity removal

Multi-step DeFi operations (query, approve, remove)

PancakeSwap Router V2

PancakeSwap Router V2 address

Slippage tolerance in percentage

First token address (e.g., USDT)

First token decimals

First token symbol for display

Second token address (e.g., BUSD)

Second token decimals

Second token symbol for display

Must have BNB for gas fees

Must own LP tokens for the pair

Remove Liquidity from Token-Token Pool

Token A balance should increase

Token B balance should increase


Query PancakeSwap Pair Reserves

Query the reserve amounts of both tokens in a PancakeSwap liquidity pair

Get the reserves of the {token0_symbol}/{token1_symbol} pair at {pair_address}

Query the liquidity reserves for pair {pair_address}

Check the reserve0 and reserve1 for the PancakeSwap pair {pair_address}

What are the current reserves of the {token0_symbol}/{token1_symbol} liquidity pair?

PancakeSwap pair contract address

USDT/BUSD LP pair on BSC

Token0 address in the pair

USDT is token0 in USDT/BUSD pair

Token0 decimal places

Token0 symbol for display

Token1 address in the pair

BUSD is token1 in USDT/BUSD pair

Token1 decimal places

Token1 symbol for display

Query executed successfully

Return format correct (includes reserve0, reserve1, blockTimestampLast)

Reserve values match actual on-chain data

Query PancakeSwap pair reserves using getReserves()

Understand liquidity pool reserve structure

Handle tuple return values (reserve0, reserve1, blockTimestampLast)

PancakeSwap pair contract address

USDT/BUSD LP pair on BSC

Token0 address in the pair

USDT is token0 in USDT/BUSD pair

Token0 decimal places

Token0 symbol for display

Token1 address in the pair

BUSD is token1 in USDT/BUSD pair

Token1 decimal places

Token1 symbol for display

Query PancakeSwap Pair Reserves

Query executed successfully