You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UniswapV2 pairFor返回错误合约地址致添加流动性失败

问题产生原因
  • 核心错误是init code hash的传参格式错误。原代码中hex'96e8ac42...'是Solidity原生的十六进制字面量写法,会被直接解析为32字节的原始二进制值参与哈希计算;但你修改后的代码传入的是带0x前缀的普通字符串'0x932b4f40...',abi.encodePacked处理字符串时会将每个字符按ASCII编码逐字节打包,最终会传入66字节的无效数据(2个字符的0x+64个十六进制字符,共66个ASCII字符),直接导致哈希计算结果完全错误。
  • 本地计算init code hash的方式可能存在偏差。如果UniswapV2Pair合约存在自定义修改、构造函数带参数、编译版本/优化选项和实际部署时不一致,type(UniswapV2Pair).creationCode计算出的哈希会和链上实际部署用的字节码哈希不匹配。
  • 额外常见诱因:旧版Ganache等测试环境存在CREATE2地址计算的兼容性bug,或者传入的factory地址错误、sortTokens排序逻辑不符合UniswapV2的排序规则(按地址大小升序排列),也会导致最终计算的pair地址错误。
修复方法
  1. 修正init code hash的传参格式:去掉hash值的0x前缀,使用Solidity十六进制字面量语法传值,同时修正地址类型转换逻辑适配Solidity 0.8+版本的类型检查,修正后的代码如下:
function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {
    (address token0, address token1) = sortTokens(tokenA, tokenB);
    pair = address(uint160(uint256(keccak256(abi.encodePacked(
            hex'ff',
            factory,
            keccak256(abi.encodePacked(token0, token1)),
            hex'932b4f40ffd7547443affda5e84a39f3efc69f2ca17d46f0f9427e015f0fb178'
        )))));
}

*注意:从uint256类型转换为address类型时,需要先截断为uint160类型,避免高版本Solidity抛出类型截断错误。

  1. 校验init code hash的准确性:最稳妥的hash获取方式不是本地编译计算,而是在Factory合约部署完成后,直接调用Factory合约暴露的INIT_CODE_PAIR_HASH公共常量读取链上实际存储的哈希值,用该值替换代码中的hash参数,保证和部署的合约逻辑完全一致。
  2. 增加校验逻辑:测试阶段可以在计算完pair地址后,调用Factory合约的getPair方法读取合约实际记录的pair地址,和本地计算结果做比对,确认计算逻辑正确后再接入添加流动性的业务逻辑。
  3. 测试环境兼容:如果使用Ganache做本地测试,升级到v7及以上版本,旧版本Ganache对CREATE2 opcode的实现存在已知偏差,会导致地址计算结果不符合EVM标准。

内容的提问来源于stack exchange,提问作者diamondhare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:54:18