5 token交换出现错误

尝试实现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);    
}
请先 登录 后评论

最佳答案 2022-02-26 17:32

第33行改成transfer就可以了,你用错了方法, 还有前面的授权路由是不需要的, 直接和pair交易不需要授权

请先 登录 后评论

其它 1 个回答

Tiny熊
  擅长:智能合约,以太坊
请先 登录 后评论
  • 1 关注
  • 0 收藏,3403 浏览
  • 郁闷龙 提出于 2022-02-25 22:19