Solidity 0.8.4编译报错:uint256无法显式转换为address
跨DEX代币兑换合约编译错误排查
问题详情
编译跨不同DEX兑换代币的合约时出现错误,相关代码、配置及错误信息如下:
合约代码(SwappingDex.sol)
//SPDX-License-Identifier: MIT import "./Interfaces/IUniswapV2Router02.sol"; import "./Interfaces/IUniswapV2Factory.sol"; //import "./Interfaces/IUniswapV2Pair.sol"; import "./Interfaces/IERC20.sol"; import "./Interfaces/UniswapV2Library.sol"; //import "./Interfaces/IUniswapV2Callee.sol"; pragma solidity >0.5.0 < 0.9.0; contract SwappingDex{ address public constant uniswapRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; address public constant uniswapFactory = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f; address public constant sushiSwapRouter = 0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F; address public constant sushiSwapFactory = 0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac; address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; function swappingIn2DEX(address tokenIn, address tokenOut, uint amount, address to)external payable{ address pairOnUniswap; address pairOnSushi; pairOnUniswap = IUniswapV2Factory(uniswapFactory).getPair(tokenIn, tokenOut); pairOnSushi = IUniswapV2Factory(sushiSwapFactory).getPair(tokenIn, tokenOut); require( pairOnSushi != 0x0000000000000000000000000000000000000000 && pairOnUniswap != 0x0000000000000000000000000000000000000000, "No Pair" ); address[] memory path; path = new address[](2); path[0] = tokenIn; path[1] = tokenOut; uint[]memory amountOutUniswap = IUniswapV2Router02(uniswapRouter).getAmountsOut(amount, path); IERC20(tokenIn).transferFrom(msg.sender, address(this), amount); IERC20(tokenIn).approve(uniswapRouter, amount); IUniswapV2Router02(uniswapRouter).swapETHForExactTokens{value: msg.value}( amountOutUniswap[1], path, to, block.timestamp ); }
Hardhat配置文件(hardhat.config.js)
require("@nomiclabs/hardhat-waffle"); require("@nomiclabs/hardhat-ethers"); require("dotenv").config(); module.exports = { solidity: "0.8.4", networks: { hardhat: { forking:{ url: "*******", }, }, } };
编译错误信息
TypeError: Explicit type conversion not allowed from "uint256" to "address". --> contracts/Interfaces/UniswapV2Library.sol:20:16: | 20 | pair = address(uint(keccak256(abi.encodePacked( | ^ (相关源码部分从此处开始并跨多行)
错误原因及解决方法
核心原因
Solidity 0.8.0及以上版本对类型转换的安全性做了严格升级,禁止直接将uint256类型强制转换为address类型。UniswapV2Library中的pairFor函数使用了旧版转换逻辑,在0.8.x版本下触发了该错误。
修复步骤
修改contracts/Interfaces/UniswapV2Library.sol中对应的转换代码:
原代码片段:
pair = address(uint(keccak256(abi.encodePacked( hex'ff', factory, keccak256(abi.encodePacked(tokenA, tokenB)), hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' ))));
修改为:
pair = address(uint160(uint(keccak256(abi.encodePacked( hex'ff', factory, keccak256(abi.encodePacked(tokenA, tokenB)), hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' )))));
以太坊地址本质是160位长度的数值,先将哈希结果转为uint160再转换为address,符合Solidity 0.8.x的类型转换规则。
额外逻辑提示
合约中存在一处逻辑冲突:调用swapETHForExactTokens是用ETH兑换指定数量的代币,但代码同时执行了tokenIn的转账和授权操作。如果需求是用tokenIn兑换tokenOut,应调用swapExactTokensForTokens函数;如果是用ETH兑换,则无需处理tokenIn的相关操作,需根据实际业务逻辑调整。
内容的提问来源于stack exchange,提问作者Matteo Gigli
相关产品推荐
相关产品推荐

