尝试实现pancake的路由里的token交换,
在bsc测试网测试,用wbnb交换busd能成功,但反向busd交换wbnb提示Fail with error 'BEP20: transfer amount exceeds allowance'.
测试网router_address地址
0x9Ac64Cc6e4415144C455BD8E4837Fea55603e5c3wbnb地址
0xae13d989daC2f0dEbFf460aC112a837C89BAa7cdbusd地址
0x78867BbEeF44f2326bF8DDd1941a4439382EF2A7`
我的理解是合约里有代币,然后授权给router地址,再transferFrom到pari合约地址,再调用pair中的swap就能交易了,但不知道反着交易为啥会报错.
代码如下:
pragma solidity ^0.8.0;
contract SWAP {
address public owner;
modifier isOwner(){
require(msg.sender == owner,"not owner");
_;
}
constructor () {
owner = msg.sender;
}
receive() external payable {}
function swap(address input, address output,address router_add,uint amountIn,uint amountOut) external isOwner {
IERC20(input).approve(router_add,115792089237316195423570985008687907853269984665640564039457584007913129639935);
Irouter router1 = Irouter(router_add);
address pair_add = Ifactory(router1.factory()).getPair(input,output);
Ipair pair1 = Ipair(pair_add);
uint256 amount0Out;
uint256 amount1Out;
address token0;
{
(uint256 reserve0,uint256 reserve1,) = pair1.getReserves();
(token0, ) = input < output ? (input, output) : (output, input);
(uint256 reserveInput,uint256 reserveOutput) =
input == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
uint256 amountOutNew = router1.getAmountOut(amountIn,reserveInput,reserveOutput);
require(amountOut <= amountOutNew,"e");
amountOut = amountOutNew;
}
(amount0Out, amount1Out) =
input == token0 ? (uint256(0), amountOut) : (amountOut, uint256(0));
IERC20(input).transferFrom(address(this),pair_add,amountIn);
pair1.swap(amount0Out,amount1Out,address(this), new bytes(0));
}
}
interface Irouter {
function factory() external pure returns (address);
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
}
interface Ipair {
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
}
interface Ifactory {
function getPair(address tokenA, address tokenB) external view returns (address pair);
}
interface IERC20 {
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}