30 【真的需要帮助】调用Uniswap的交易功能"swapExactTokensForTokens"出错

我正在使用Vyper写了一个合约用来实现调用Uniswap的交易功能,但是部署完之后无法正常使用,我也不知道哪里出现了问题,很困惑,有大佬帮忙解答吗?代码中的合约地址是Rinkeby的。 真的非常需要帮助!!求助

remix 调用的时候一直显示这个弹窗,无法正在实现

image.png

调用失败的Hash: https://rinkeby.etherscan.io/tx/0x9c481a6ba0fc997f4a5cf058307c239a51128b28d391718d7a1209833787acb1

以下是我的代码:

# @version ^0.2

from vyper.interfaces import ERC20

interface UniswapRouter:
    def swapExactTokensForTokens(
        amountIn: uint256,
        amountOutMin: uint256,
        path: address[3],
        to: address,
        deadline: uint256
    ) -> uint256[3]: nonpayable

UNISWAP_ROUTER: constant(address) = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
UNISWAP_FACTORY: constant(address) = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f
WETH: constant(address) = 0xc778417E063141139Fce010982780140Aa0cD5Ab
USDC: constant(address) = 0xeb8f08a975Ab53E34D8a0330E0D34de942C95926

owner: public(address)
receiver: public(address)
is_approved: HashMap[address, HashMap[address, bool]]

@external
def __init__(_receiver: address):
    self.owner = msg.sender
    self.receiver = _receiver

@external
def swapper(_coin: address) -> bool:
    amount: uint256 = ERC20(_coin).balanceOf(msg.sender)
    if amount != 0:
        response: Bytes[32] = raw_call(
            _coin,
            concat(
                method_id("transferFrom(address,address,uint256)"),
                convert(msg.sender, bytes32),
                convert(self, bytes32),
                convert(amount, bytes32)
            ),
            max_outsize=32
        )
        if len(response) != 0:
            assert convert(response, bool)

    amount = ERC20(_coin).balanceOf(self)

    if not self.is_approved[UNISWAP_ROUTER][_coin]:
        response: Bytes[32] = raw_call(
            _coin,
            concat(
                method_id("approve(address,uint256)"),
                convert(UNISWAP_ROUTER, bytes32),
                convert(MAX_UINT256, bytes32)
            ),
            max_outsize=32
        )
        if len(response) != 0:
            assert convert(response, bool)
        self.is_approved[UNISWAP_ROUTER][_coin] = True

    raw_call(
        UNISWAP_ROUTER,
        concat(
            method_id("swapExactTokensForTokens(uint256,uint256,address[],address,uint256)"),
            convert(amount, bytes32),
            EMPTY_BYTES32,
            convert(160, bytes32),
            convert(self.receiver, bytes32),
            convert(block.timestamp, bytes32),
            convert(3, bytes32),
            convert(_coin, bytes32),
            convert(WETH, bytes32),
            convert(USDC, bytes32)
        )
    )

    return True
请先 登录 后评论

最佳答案 2022-03-30 14:46

python 语法 我目测看出几个有问题的地方或者需要注意的地方。假定:你的逻辑是token地址,将调用这所有余额兑换成另外一个token。把该合约命名为robot。 1.值得注意,调用这段代码之前应该确保,msg.sender 有批准robot扣除_coin approve对应额度的权限。

_coin,
            concat(
                method_id("transferFrom(address,address,uint256)"),
                convert(msg.sender, bytes32),
                convert(self, bytes32),
                convert(amount, bytes32)
            ),

2.rlp编码部分没问题,但是需要确保交换的流动性池子是存在的并且是v2的池子,也就是_coin,weth的流动池。

其他方面需要你发起一笔交易把hash贴出来才能知道了

请先 登录 后评论

其它 2 个回答

zen
请先 登录 后评论
1312930610
请先 登录 后评论
  • 2 关注
  • 0 收藏,4653 浏览
  • 0x77 提出于 2022-03-29 22:24