Polygon主网分叉环境下AAVE V3 supply()交易回滚问题排查
解决Hardhat分叉Polygon主网调用AAVE V3 supply函数回滚问题
核心问题:代币地址与网络环境不匹配
你当前分叉的是Polygon主网,但代码中使用了测试网MATIC代币地址(0xD65d229951E94a7138F47Bd9e0Faff42A7aCe0c6),这个地址在主网分叉链上是无效合约,直接导致approve和后续supply调用无理由回滚。
修复步骤
1. 替换为Polygon主网MATIC地址
将代码中的MATIC地址改为主网官方地址:
const maticTokenAddress = "0x0000000000000000000000000000000000001010"; // Polygon主网MATIC
2. 确保测试账户有足够MATIC余额
分叉主网后,默认deployer账户仅持有ETH,无MATIC余额。可通过Hardhat的账户模拟功能,从主网巨鲸地址转账MATIC到deployer:
// 在main函数开头添加转账逻辑 const maticHolder = "0xf977814e90da44bfa03b6295a0616a897441acec"; // 主网MATIC巨鲸地址 await hre.network.provider.request({ method: "hardhat_impersonateAccount", params: [maticHolder], }); const signer = await ethers.getSigner(maticHolder); const maticToken = await ethers.getContractAt("IERC20", maticTokenAddress, signer); await maticToken.transfer(deployer, AMOUNT); await hre.network.provider.request({ method: "hardhat_stopImpersonatingAccount", params: [maticHolder], });
3. 验证合约ABI完整性
确保IPool和IPoolAddressesProvider的ABI包含正确的函数签名,例如supply函数的定义需与AAVE V3官方一致:
interface IPool { function supply( address asset, uint256 amount, address onBehalfOf, uint16 referralCode ) external; }
4. 配置合适的分叉块高
若分叉的块高过早,可能AAVE V3合约尚未部署或资产未启用。在hardhat.config.js中指定AAVE V3部署后的块高:
module.exports = { networks: { hardhat: { forking: { url: "https://polygon-mainnet.infura.io/v3/YOUR_API_KEY", blockNumber: 45000000, // 选择AAVE V3部署后的块高 }, }, }, };
修复后完整测试脚本示例
const { getNamedAccounts, ethers, hre } = require("hardhat"); async function main() { const { deployer } = await getNamedAccounts(); const AMOUNT = ethers.utils.parseEther("0.11"); const maticTokenAddress = "0x0000000000000000000000000000000000001010"; // Polygon主网MATIC // 给deployer转账MATIC const maticHolder = "0xf977814e90da44bfa03b6295a0616a897441acec"; await hre.network.provider.request({ method: "hardhat_impersonateAccount", params: [maticHolder], }); const signer = await ethers.getSigner(maticHolder); const maticToken = await ethers.getContractAt("IERC20", maticTokenAddress, signer); await maticToken.transfer(deployer, AMOUNT); await hre.network.provider.request({ method: "hardhat_stopImpersonatingAccount", params: [maticHolder], }); const Pool = await getPool(deployer); await approveErc20(maticTokenAddress, Pool.address, AMOUNT, deployer); console.log("Depositing..."); console.log("Address provided: ", Pool.address); await Pool.supply(maticTokenAddress, AMOUNT, deployer, 0); console.log("Deposited!"); } async function getPool(account) { const PoolAddressesProvider = await ethers.getContractAt( "IPoolAddressesProvider", "0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb", // Polygon主网地址提供者 account ); const PoolAddress = await PoolAddressesProvider.getPool(); const Pool = await ethers.getContractAt("IPool", PoolAddress, account); return Pool; } async function approveErc20(erc20Address, spenderAddress, amountToSpend, account) { const erc20Token = await ethers.getContractAt("IERC20", erc20Address, account); const tx = await erc20Token.approve(spenderAddress, amountToSpend); await tx.wait(1); console.log("Approved!"); } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
内容的提问来源于stack exchange,提问作者Daniel Beltrán
相关产品推荐
相关产品推荐

