在新的uniswap v3.0中还多了一个参数
对于计算池地址 - 费用金额以百分比表示,定义如下sdk https://docs.uniswap.org/sdk/reference/enums/FeeAmount与 uint24 类型。
从sdk的computePoolAddress https://github.com/Uniswap/v3-sdk/blob/aeb1b09/src/utils/computePoolAddress.ts#L7第一次解决
对于计算池地址问题,有一个令我困惑的部分来源
[defaultAbiCoder.encode(['address', 'address', 'uint24'], [token0.address, token1.address, fee])
为什么我决定使用它来计算它encodePacked
(i.e. encode_abi_packed
对于 python3(来自 eth_abi.packed)函数。但它产生了错误的结果。
深入了解 uniswap v3.0 外围矿池合约 -3 https://github.com/Uniswap/v3-periphery/blob/v1.0.0/contracts/libraries/PoolAddress.sol澄清了
我的错。事实证明在 3.0 版本中使用encode
(i.e. encode_abi
对于 python3,来自 eth_abi) 函数。更多解释here https://forum.openzeppelin.com/t/abi-encode-vs-abi-encodepacked/2948/2
因此,将所有内容耦合在一起。
借助 python3 计算池地址的主要函数。
from web3 import Web3
from eth_abi.packed import encode_abi_packed
from eth_abi import encode_abi
def compute_pairs_address_with_target_v3(factory = '0x1F98431c8aD98523631AE4a59f267346ea31F984', token_0 = None, token_1 = None, fee = 3000):
POOL_INIT_CODE_HASH = '0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54'
token_0 = Web3.toChecksumAddress(token_0)
token_1 = Web3.toChecksumAddress(token_1)
abiEncoded_1 = encode_abi(['address', 'address', 'uint24'], (token_0, token_1, fee )) if int(token_0,16)<int(token_1,16) else encode_abi(['address', 'address', 'uint24'], (token_1, token_0, fee ))
salt = Web3.solidityKeccak(['bytes'], ['0x' +abiEncoded_1.hex()])
abiEncoded_2 = encode_abi_packed([ 'address', 'bytes32'], ( factory, salt))
resPair = Web3.solidityKeccak(['bytes','bytes'], ['0xff' + abiEncoded_2.hex(), POOL_INIT_CODE_HASH])[12:]
return(resPair.hex())
对其进行测试,基于4 https://github.com/Uniswap/v3-sdk/blob/aeb1b09d454dad50718a3517eb9e73b080ee4833/src/utils/computePoolAddress.test.ts and 5 https://info.uniswap.org/#/pools/0x290a6a7460b308ee3f19023d2d00de604bcf5b42
factoryAddress = '0x1111111111111111111111111111111111111111'
token0 = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
token1 = '0x6B175474E89094C44Da98b954EedeAC495271d0F'
fee = 500 #https://docs.uniswap.org/sdk/reference/enums/FeeAmount#low
targetPoolAddress = '0x90B1b09A9715CaDbFD9331b3A7652B24BfBEfD32'
assert(targetPoolAddress.lower() == compute_pairs_address_with_target_v3(factory = factoryAddress, token_0 = token0, token_1 = token1, fee = fee).lower())
token0 = '0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0'
token1 = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'
factoryAddress = '0x1F98431c8aD98523631AE4a59f267346ea31F984'
fee = 3000 #https://docs.uniswap.org/sdk/reference/enums/FeeAmount#medium
targetPoolAddress = '0x290a6a7460b308ee3f19023d2d00de604bcf5b42' #WETH /MATIC 0.3 % fee
assert(targetPoolAddress.lower() == compute_pairs_address_with_target_v3(factory = factoryAddress, token_0 = token0, token_1 = token1, fee = fee).lower())