Uniswap 方法 getAmountsOut() returns 使用 Hardhat 主网分叉时的错误值
Uniswap method getAmountsOut() returns wrong value when using Hardhat mainnet fork
在我的安全帽测试中,我使用 Uniswap 的 getAmountsOut
来获取以美元为单位的 ETH 价格(使用 DAI)。目前 returns 2766 美元作为 ETH 的价格是正确的。这是我成功获取价格的测试:
require('dotenv').config()
const { ethers } = require("hardhat");
const UNISWAPV2_ROUTER02_ADDRESS = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D";
const UNISWAPV2_ROUTER02_ABI = [{ "inputs": [{ "internalType": "uint256", "name": "amountIn", "type": "uint256" }, { "internalType": "address[]", "name": "path", "type": "address[]" }], "name": "getAmountsOut", "outputs": [{ "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }], "stateMutability": "view", "type": "function" }]
const DAI_ADDRESS = "0x6b175474e89094c44da98b954eedeac495271d0f";
const WETH_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
describe("eth-price-test", function () {
it("Test fetch Eth price", async function () {
const provider = new ethers.providers.WebSocketProvider(process.env.INFURA_WEB_SOCKET)
const wallet = new ethers.Wallet(process.env.ETH_PRIVATE_KEY, provider)
const signer = wallet.provider.getSigner(wallet.address)
let uniswap = new ethers.Contract(
UNISWAPV2_ROUTER02_ADDRESS,
UNISWAPV2_ROUTER02_ABI,
signer,
);
const amountEth = await uniswap.getAmountsOut(
1,
[WETH_ADDRESS, DAI_ADDRESS]
)
console.log(`1 Eth = ${amountEth[1].toString()} USD`)
});
});
然而,当我使用连接到 Hardhat 主网分叉的签名者时,返回的价格是 3993 美元,这要高得多。我得到这样的签名者:
signer = ethers.provider.getSigner(process.env.ETH_PUBLIC_KEY)
let uniswap = new ethers.Contract(
UNISWAPV2_ROUTER02_ADDRESS,
UNISWAPV2_ROUTER02_ABI,
signer,
);
这里是我的hardhat.config.js的相关部分供参考:
module.exports = {
solidity: "0.5.0",
networks: {
hardhat: {
forking: {
url: process.env.ALCHEMY_URL
}
}
}
};
知道为什么会有这么大的价格差异吗?即使我将主网分叉挂到不同的区块,它总是 returns $3993...
提前致谢!
我找到了修复方法!通过在部署 Uniswap 合约时使用 ethers.provider
而不是 signer
,getAmountsOut()
将使用挂钩区块正确获取 Eth 的价格。
let uniswap = new ethers.Contract(
UNISWAPV2_ROUTER02_ADDRESS,
UNISWAPV2_ROUTER02_ABI,
ethers.provider // using provider instead of signer here
);
在我的安全帽测试中,我使用 Uniswap 的 getAmountsOut
来获取以美元为单位的 ETH 价格(使用 DAI)。目前 returns 2766 美元作为 ETH 的价格是正确的。这是我成功获取价格的测试:
require('dotenv').config()
const { ethers } = require("hardhat");
const UNISWAPV2_ROUTER02_ADDRESS = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D";
const UNISWAPV2_ROUTER02_ABI = [{ "inputs": [{ "internalType": "uint256", "name": "amountIn", "type": "uint256" }, { "internalType": "address[]", "name": "path", "type": "address[]" }], "name": "getAmountsOut", "outputs": [{ "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }], "stateMutability": "view", "type": "function" }]
const DAI_ADDRESS = "0x6b175474e89094c44da98b954eedeac495271d0f";
const WETH_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
describe("eth-price-test", function () {
it("Test fetch Eth price", async function () {
const provider = new ethers.providers.WebSocketProvider(process.env.INFURA_WEB_SOCKET)
const wallet = new ethers.Wallet(process.env.ETH_PRIVATE_KEY, provider)
const signer = wallet.provider.getSigner(wallet.address)
let uniswap = new ethers.Contract(
UNISWAPV2_ROUTER02_ADDRESS,
UNISWAPV2_ROUTER02_ABI,
signer,
);
const amountEth = await uniswap.getAmountsOut(
1,
[WETH_ADDRESS, DAI_ADDRESS]
)
console.log(`1 Eth = ${amountEth[1].toString()} USD`)
});
});
然而,当我使用连接到 Hardhat 主网分叉的签名者时,返回的价格是 3993 美元,这要高得多。我得到这样的签名者:
signer = ethers.provider.getSigner(process.env.ETH_PUBLIC_KEY)
let uniswap = new ethers.Contract(
UNISWAPV2_ROUTER02_ADDRESS,
UNISWAPV2_ROUTER02_ABI,
signer,
);
这里是我的hardhat.config.js的相关部分供参考:
module.exports = {
solidity: "0.5.0",
networks: {
hardhat: {
forking: {
url: process.env.ALCHEMY_URL
}
}
}
};
知道为什么会有这么大的价格差异吗?即使我将主网分叉挂到不同的区块,它总是 returns $3993...
提前致谢!
我找到了修复方法!通过在部署 Uniswap 合约时使用 ethers.provider
而不是 signer
,getAmountsOut()
将使用挂钩区块正确获取 Eth 的价格。
let uniswap = new ethers.Contract(
UNISWAPV2_ROUTER02_ADDRESS,
UNISWAPV2_ROUTER02_ABI,
ethers.provider // using provider instead of signer here
);