气体估计错误 - 执行{; quartiqual':{code':3,data; data':“ 0xfb7f5079 }}}
我在Rinkeby Testnet上部署了一份合同。它基本上是uniswapv2的克隆。 每当我尝试调用路由器合同的附加功能/删除液体/ Swaptokens功能时,此错误就会弹出。其他合同中的所有其他职能都很好!路由器合同的功能只会给出此错误!
目前,我无法纠正这个问题,并提出了一些使它起作用的方法!这是参考的代码:
//SPDX-License-Identifier: MIT
pragma solidity >=0.8.10;
import "../interfaces/IKswapPair.sol";
import "../interfaces/IKswapFactory.sol";
import "./KswapLibrary.sol";
contract KswapRouter {
error ExcessiveInputAmount();
error InsufficientAAmount();
error InsufficientBAmount();
error InsufficientOutputAmount();
error SafeTransferFailed();
IKswapFactory factory;
constructor(address factoryAddress) {
factory = IKswapFactory(factoryAddress);
}
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to
)
public
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
)
{
if (factory.pairs(tokenA, tokenB) == address(0)) {
factory.createPair(tokenA, tokenB);
}
(amountA, amountB) = _calculateLiquidity(
tokenA,
tokenB,
amountADesired,
amountBDesired,
amountAMin,
amountBMin
);
address pairAddress = KswapLibrary.pairFor(
address(factory),
tokenA,
tokenB
);
_safeTransferFrom(tokenA, msg.sender, pairAddress, amountA);
_safeTransferFrom(tokenB, msg.sender, pairAddress, amountB);
liquidity = IKswapPair(pairAddress).mint(to);
}
function removeLiquidity(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to
) public returns (uint256 amountA, uint256 amountB) {
address pair = KswapLibrary.pairFor(
address(factory),
tokenA,
tokenB
);
IKswapPair(pair).transferFrom(msg.sender, pair, liquidity);
(amountA, amountB) = IKswapPair(pair).burn(to);
if (amountA < amountAMin) revert InsufficientAAmount();
if (amountB < amountBMin) revert InsufficientBAmount();
}
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to
) public returns (uint256[] memory amounts) {
amounts = KswapLibrary.getAmountsOut(
address(factory),
amountIn,
path
);
if (amounts[amounts.length - 1] < amountOutMin)
revert InsufficientOutputAmount();
_safeTransferFrom(
path[0],
msg.sender,
KswapLibrary.pairFor(address(factory), path[0], path[1]),
amounts[0]
);
_swap(amounts, path, to);
}
function swapTokensForExactTokens(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to
) public returns (uint256[] memory amounts) {
amounts = KswapLibrary.getAmountsIn(
address(factory),
amountOut,
path
);
if (amounts[amounts.length - 1] > amountInMax)
revert ExcessiveInputAmount();
_safeTransferFrom(
path[0],
msg.sender,
KswapLibrary.pairFor(address(factory), path[0], path[1]),
amounts[0]
);
_swap(amounts, path, to);
}
//
//
//
// PRIVATE
//
//
//
function _swap(
uint256[] memory amounts,
address[] memory path,
address to_
) internal {
for (uint256 i = 0; i < path.length - 1; i++) {
(address input, address output) = (path[i], path[i + 1]);
(address token0, ) = KswapLibrary.sortTokens(input, output);
uint256 amountOut = amounts[i + 1];
(uint256 amount0Out, uint256 amount1Out) = input == token0
? (uint256(0), amountOut)
: (amountOut, uint256(0));
address to = i < path.length - 2
? KswapLibrary.pairFor(address(factory), output, path[i + 2])
: to_;
IKswapPair(
KswapLibrary.pairFor(address(factory), input, output)
).swap(amount0Out, amount1Out, to);
}
}
function _calculateLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin
) internal returns (uint256 amountA, uint256 amountB) {
(uint256 reserveA, uint256 reserveB) = KswapLibrary.getReserves(
address(factory),
tokenA,
tokenB
);
if (reserveA == 0 && reserveB == 0) {
(amountA, amountB) = (amountADesired, amountBDesired);
} else {
uint256 amountBOptimal = KswapLibrary.quote(
amountADesired,
reserveA,
reserveB
); //calculates output amount
if (amountBOptimal <= amountBDesired) {
if (amountBOptimal <= amountBMin) revert InsufficientBAmount();
(amountA, amountB) = (amountADesired, amountBOptimal);
} else {
uint256 amountAOptimal = KswapLibrary.quote(
amountBDesired,
reserveB,
reserveA
);
assert(amountAOptimal <= amountADesired);
if (amountAOptimal <= amountAMin) revert InsufficientAAmount();
(amountA, amountB) = (amountAOptimal, amountBDesired);
}
}
}
function _safeTransferFrom(
address token,
address from,
address to,
uint256 value
) private {
(bool success, bytes memory data) = token.call(
abi.encodeWithSignature(
"transferFrom(address,address,uint256)",
from,
to,
value
)
);
if (!success || (data.length != 0 && !abi.decode(data, (bool))))
revert SafeTransferFailed();
}
//
//
// LIBRARY FUNCTIONS
//
//
function quote(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) public pure returns (uint256 amountOut) {
return KswapLibrary.quote(amountIn, reserveIn, reserveOut);
}
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) public pure returns (uint256 amountOut) {
return KswapLibrary.getAmountOut(amountIn, reserveIn, reserveOut);
}
function getAmountIn(
uint256 amountOut,
uint256 reserveIn,
uint256 reserveOut
) public pure returns (uint256 amountIn) {
return KswapLibrary.getAmountIn(amountOut, reserveIn, reserveOut);
}
function getAmountsOut(uint256 amountIn, address[] memory path)
public
returns (uint256[] memory amounts)
{
return KswapLibrary.getAmountsOut(address(factory), amountIn, path);
}
function getAmountsIn(uint256 amountOut, address[] memory path)
public
returns (uint256[] memory amounts)
{
return KswapLibrary.getAmountsIn(address(factory), amountOut, path);
}
}
I have a contract deployed on the rinkeby testnet. It is basically a clone of uniswapV2.
Whenever I try to call the router contract's addLiquidity/ removeLiquidity/ swapTokens functions this error pops up. All other functions in other contracts are working just fine! Only functions of the router contract are giving this error!
I am unable to rectify this problem at the moment kindly look into this and suggest some ways to make it work! Here is the code for reference:
//SPDX-License-Identifier: MIT
pragma solidity >=0.8.10;
import "../interfaces/IKswapPair.sol";
import "../interfaces/IKswapFactory.sol";
import "./KswapLibrary.sol";
contract KswapRouter {
error ExcessiveInputAmount();
error InsufficientAAmount();
error InsufficientBAmount();
error InsufficientOutputAmount();
error SafeTransferFailed();
IKswapFactory factory;
constructor(address factoryAddress) {
factory = IKswapFactory(factoryAddress);
}
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to
)
public
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
)
{
if (factory.pairs(tokenA, tokenB) == address(0)) {
factory.createPair(tokenA, tokenB);
}
(amountA, amountB) = _calculateLiquidity(
tokenA,
tokenB,
amountADesired,
amountBDesired,
amountAMin,
amountBMin
);
address pairAddress = KswapLibrary.pairFor(
address(factory),
tokenA,
tokenB
);
_safeTransferFrom(tokenA, msg.sender, pairAddress, amountA);
_safeTransferFrom(tokenB, msg.sender, pairAddress, amountB);
liquidity = IKswapPair(pairAddress).mint(to);
}
function removeLiquidity(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to
) public returns (uint256 amountA, uint256 amountB) {
address pair = KswapLibrary.pairFor(
address(factory),
tokenA,
tokenB
);
IKswapPair(pair).transferFrom(msg.sender, pair, liquidity);
(amountA, amountB) = IKswapPair(pair).burn(to);
if (amountA < amountAMin) revert InsufficientAAmount();
if (amountB < amountBMin) revert InsufficientBAmount();
}
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to
) public returns (uint256[] memory amounts) {
amounts = KswapLibrary.getAmountsOut(
address(factory),
amountIn,
path
);
if (amounts[amounts.length - 1] < amountOutMin)
revert InsufficientOutputAmount();
_safeTransferFrom(
path[0],
msg.sender,
KswapLibrary.pairFor(address(factory), path[0], path[1]),
amounts[0]
);
_swap(amounts, path, to);
}
function swapTokensForExactTokens(
uint256 amountOut,
uint256 amountInMax,
address[] calldata path,
address to
) public returns (uint256[] memory amounts) {
amounts = KswapLibrary.getAmountsIn(
address(factory),
amountOut,
path
);
if (amounts[amounts.length - 1] > amountInMax)
revert ExcessiveInputAmount();
_safeTransferFrom(
path[0],
msg.sender,
KswapLibrary.pairFor(address(factory), path[0], path[1]),
amounts[0]
);
_swap(amounts, path, to);
}
//
//
//
// PRIVATE
//
//
//
function _swap(
uint256[] memory amounts,
address[] memory path,
address to_
) internal {
for (uint256 i = 0; i < path.length - 1; i++) {
(address input, address output) = (path[i], path[i + 1]);
(address token0, ) = KswapLibrary.sortTokens(input, output);
uint256 amountOut = amounts[i + 1];
(uint256 amount0Out, uint256 amount1Out) = input == token0
? (uint256(0), amountOut)
: (amountOut, uint256(0));
address to = i < path.length - 2
? KswapLibrary.pairFor(address(factory), output, path[i + 2])
: to_;
IKswapPair(
KswapLibrary.pairFor(address(factory), input, output)
).swap(amount0Out, amount1Out, to);
}
}
function _calculateLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin
) internal returns (uint256 amountA, uint256 amountB) {
(uint256 reserveA, uint256 reserveB) = KswapLibrary.getReserves(
address(factory),
tokenA,
tokenB
);
if (reserveA == 0 && reserveB == 0) {
(amountA, amountB) = (amountADesired, amountBDesired);
} else {
uint256 amountBOptimal = KswapLibrary.quote(
amountADesired,
reserveA,
reserveB
); //calculates output amount
if (amountBOptimal <= amountBDesired) {
if (amountBOptimal <= amountBMin) revert InsufficientBAmount();
(amountA, amountB) = (amountADesired, amountBOptimal);
} else {
uint256 amountAOptimal = KswapLibrary.quote(
amountBDesired,
reserveB,
reserveA
);
assert(amountAOptimal <= amountADesired);
if (amountAOptimal <= amountAMin) revert InsufficientAAmount();
(amountA, amountB) = (amountAOptimal, amountBDesired);
}
}
}
function _safeTransferFrom(
address token,
address from,
address to,
uint256 value
) private {
(bool success, bytes memory data) = token.call(
abi.encodeWithSignature(
"transferFrom(address,address,uint256)",
from,
to,
value
)
);
if (!success || (data.length != 0 && !abi.decode(data, (bool))))
revert SafeTransferFailed();
}
//
//
// LIBRARY FUNCTIONS
//
//
function quote(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) public pure returns (uint256 amountOut) {
return KswapLibrary.quote(amountIn, reserveIn, reserveOut);
}
function getAmountOut(
uint256 amountIn,
uint256 reserveIn,
uint256 reserveOut
) public pure returns (uint256 amountOut) {
return KswapLibrary.getAmountOut(amountIn, reserveIn, reserveOut);
}
function getAmountIn(
uint256 amountOut,
uint256 reserveIn,
uint256 reserveOut
) public pure returns (uint256 amountIn) {
return KswapLibrary.getAmountIn(amountOut, reserveIn, reserveOut);
}
function getAmountsOut(uint256 amountIn, address[] memory path)
public
returns (uint256[] memory amounts)
{
return KswapLibrary.getAmountsOut(address(factory), amountIn, path);
}
function getAmountsIn(uint256 amountOut, address[] memory path)
public
returns (uint256[] memory amounts)
{
return KswapLibrary.getAmountsIn(address(factory), amountOut, path);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论