Uniswap v4 introduces a new architecture for creating customizable hooks, providing developers with powerful tools to extend and enhance the functionality of the protocol. This tutorial will guide you through building Uniswap v4 hooks using the v4-template and leveraging ethui to streamline the development process. We'll cover setup, development, testing, and debugging through a technical walkthrough with practical examples.

Prerequisites

Before diving in, ensure you have the following:

  • Foundry: A powerful Ethereum development framework.

  • Anvil: A local EVM chain simulator.

  • ethui: A UI toolkit for Ethereum development.

Step 1: Setting Up the v4-template

  1. Clone the v4-template Repository

    git clone https://github.com/uniswapfoundation/v4-template.git
    cd v4-template
    
  2. Install Dependencies Ensure you have Foundry installed. Then, run:

    forge install
    forge test
    
  3. Local Development with Anvil Start Anvil in a new terminal:

    anvil
    

    In another terminal, deploy the hooks on the local Anvil chain:

    forge script script/Anvil.s.sol --rpc-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --broadcast
    

Step 2: Developing a Hook

Let's create a hook that logs various events such as swaps and liquidity changes. We'll use the provided Counter.sol as a starting point.

  1. Modify Counter.sol to Track Events

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.24;
    
    ...
    
    contract Counter is BaseHook {
        using PoolIdLibrary for PoolKey;
    
        mapping(PoolId => uint256) public beforeSwapCount;
        mapping(PoolId => uint256) public afterSwapCount;
    
        mapping(PoolId => uint256) public beforeAddLiquidityCount;
        mapping(PoolId => uint256) public beforeRemoveLiquidityCount;
    
        constructor(IPoolManager _poolManager) BaseHook(_poolManager) {}
    ...
    }
    
  2. Test the Hook Create a test file to validate the hook's functionality.

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.24;
    ...
    contract CounterTest is Test, Deployers {
        using PoolIdLibrary for PoolKey;
        using CurrencyLibrary for Currency;
    
        Counter counter;
        PoolId poolId;
    
        function setUp() public {
          ...
        }
    
        function testCounterHooks() public {
            // positions were created in setup()
            assertEq(counter.beforeAddLiquidityCount(poolId), 3);
            assertEq(counter.beforeRemoveLiquidityCount(poolId), 0);
    
            assertEq(counter.beforeSwapCount(poolId), 0);
            assertEq(counter.afterSwapCount(poolId), 0);
    
            // Perform a test swap //
            bool zeroForOne = true;
            int256 amountSpecified = -1e18; // negative number indicates exact input swap!
            BalanceDelta swapDelta = swap(key, zeroForOne, amountSpecified, ZERO_BYTES);
            // ------------------- //
    
            assertEq(int256(swapDelta.amount0()), amountSpecified);
    
            assertEq(counter.beforeSwapCount(poolId), 1);
            assertEq(counter.afterSwapCount(poolId), 1);
        }
    }
    
  3. Run Tests

    forge test
    

Step 3: Leveraging ethui for Debugging and Development

ethui is a developer's crypto wallet equipped with extensive tooling to speed up your Ethereum development workflows. Here's how to leverage ethui specifically for building hooks:

  1. Install and Configure EthUI: Download and install the latest release of ethui from the releases page. ethui automatically detects and connects to your running Anvil instance on http://localhost:8545. You can skip most of the onboarding steps (like setting up Alchemy.com) as they are primarily for mainnet usage.

    • Set Up ABI Monitoring Configure ethui to monitor your filesystem for foundry projects, indexing the output ABIs automatically.
  2. Enable Foundry Integrations: ethui will automatically index ABIs for contracts within your Foundry project, making them readily available within the interface.

    • Navigate to Settings: Open ethui and navigate to the "Foundry" settings.

    • Set ABI Watch Path: Enter the path to your v4-template project directory. For example:

      /Users/username/v4-template
      

Se†ting up ABI-watch path in ethui

  • Real-time Transaction Editing and Debugging: ethui provides a powerful transaction explorer that decodes calldata and displays human-readable information about your contract interactions:

    • Open Transactions: Navigate to the "Transactions" tab in ethui. Each transaction related to your contracts will be listed.

      • View Decoded Data: Selecting a transaction reveals its details:

        • Function Call: Clearly see which function of your contract was invoked (e.g., swap, addLiquidity).

        • Decoded Parameters: ethui automatically decodes calldata, showing the exact values passed to your hook functions, significantly simplifying the debugging process.

Transaction calldata inspection window in ethui

  • Transaction Simulation & Replay: ethui empowers you to test your hooks under various conditions without redeploying contracts:

    • Navigate to Contracts: Go to the "Contracts" tab, where your indexed Foundry contracts appear.

    • Select Your Hook Contract: Choose your deployed hook contract (e.g., Counter).

    • Simulate Transactions: The interface provides a user-friendly way to interact with your contract:

      • Select Function: Choose the specific hook function you want to test.

      • Input Parameters: Provide different input values to your hook function, simulating various scenarios.

      • Execute Simulation: ethui executes the transaction against your local Anvil instance, displaying the results. This enables you to rapidly iterate and test your hook logic.

Execute transactions seamlessly from ethui's contracts panel

Advanced Debugging with ethui

ethui goes beyond basic debugging:

  • Edit & Replay Transactions: The "Send Again" button in the Transaction tab allows you to modify transaction parameters and resend, enabling you to quickly test different scenarios or fix bugs in your hook logic without redeploying.

  • Multiple Wallet Management: Easily manage multiple wallets within ethui. This is useful for simulating interactions from different addresses (e.g., liquidity providers, swappers) when testing your hooks.

Example: Debugging a Swap Event with ethui

Let's say your Counter hook isn't correctly incrementing the afterSwapCount. Here's how ethui helps:

  1. Trigger a Swap: Initiate a swap transaction that should invoke your hook, either programmatically or using the ethui interface.

  2. Inspect the Transaction: In ethui's Transactions tab, find the swap transaction.

  3. Verify Hook Execution: Examine the decoded transaction data. You should see a call to your hook contract's functions (e.g., beforeSwap, afterSwap).

  4. Inspect State Changes: Open your Counter contract in the "Contracts" tab and read the value of afterSwapCount for the relevant pool. If it's not incrementing, you've isolated the problem area in your hook's logic.

  5. Debug with Simulations: Use ethui's transaction simulation to call the problematic hook function directly with various inputs. This iterative process helps pinpoint the logic flaw in your code.

By combining the v4-template and ethui, you can efficiently develop, test, and debug custom hooks for Uniswap v4. This setup not only accelerates the development process but also provides robust tools for ensuring the reliability and security of your hooks.

For more advanced hook implementations and examples, refer to the v4-periphery repository and v4-by-example.

We encourage you to report any bugs or suggestions for ethui. You can do this through GitHub issues or by reaching out directly to naps62 on telegram!

Happy coding! 🦄

Mirror文章信息

Mirror原文:查看原文

作者地址:0xD1B670E5413a4d08C02A561f57259817199D586a

内容类型:application/json

应用名称:MirrorXYZ

内容摘要:K_JXHPjhPuPXJqVu_9thEs6DfslCuSOR1bwCvMb2w9Q

原始内容摘要:cEy4P1ylBXA4wgBoprNVzydCtx8hKTvZO1F4esCGS5k

区块高度:1435639

发布时间:2024-05-31 18:16:08