You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sushiswap BentoBox报Transfer not approved错误如何解决

Sushiswap Trident兑换报错「BentoBox: Transfer not approved」排查

问题相关代码

用于与Sushiswap交互的Solidity函数如下:

function swapSingleParamswhitPool(
    uint256 amountIn,
    uint256 amountOutMinimum, 
    address pool, 
    address tokenIn, 
    bytes memory data) public payable {

    ITridentRouter.ExactInputSingleParams memory exactInputSingleParams = ITridentRouter.ExactInputSingleParams(amountIn, amountOutMinimum, pool, tokenIn, data);
    tridentRouter.exactInputSingle{ value: msg.value }(exactInputSingleParams);
}

报错信息

调用上述函数始终触发回滚,回滚信息如下:

{ "code": 3, "message": "execution reverted: BentoBox: Transfer not approved", "data": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001f42656e746f426f783a205472616e73666572206e6f7420617070726f76656400" }

已尝试在BentoBox中配置masterContract为授权状态、手动执行授权操作,问题仍未解决。

根因与修复方案

报错核心原因是授权链路不完整,BentoBox的授权逻辑和普通ERC20授权不同,多层授权任意一层缺失都会触发该错误,逐一排查以下点即可解决:

  • 授权主体错误:Trident执行兑换时,是BentoBox直接从发起兑换的地址划扣资产,如果你是通过合约调用exactInputSingle,那么资产持有地址是你的业务合约地址,不是你发起交易的外部钱包地址。之前手动做的授权大概率是给外部钱包地址开的权限,没有给业务合约地址开放TridentRouter的BentoBox操作权限。
  • 缺少ERC20层授权:如果输入资产是ERC20而非原生链代币(如ETH/BNB),需要先给BentoBox合约开放对应数量的ERC20转账授权,注意授权对象是BentoBox地址,不是TridentRouter地址。
  • 缺少BentoBox内部授权:需要调用BentoBox的setMasterContractApproval方法,将TridentRouter设置为当前发起兑换地址(业务合约地址)的授权masterContract,允许其操作对应地址在BentoBox内的资产。

修复后的参考实现如下:

// 替换为对应链的实际部署地址
address private constant BENTO_BOX_ADDR = 0xF5BCE5077908a1b7370B9ae04AdC565EBd643966;
IERC20 private constant NATIVE = IERC20(0x0000000000000000000000000000000000000000);

function swapSingleParamswhitPool(
    uint256 amountIn,
    uint256 amountOutMinimum, 
    address pool, 
    address tokenIn, 
    bytes memory data
) public payable {
    // 处理非原生币的ERC20层授权
    if (tokenIn != address(NATIVE)) {
        // 从调用者地址将代币转入当前合约
        IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn);
        // 给BentoBox授权对应额度的ERC20转账权限
        IERC20(tokenIn).approve(BENTO_BOX_ADDR, amountIn);
    }

    // 给TridentRouter开放BentoBox内部操作权限
    IBentoBox(BENTO_BOX_ADDR).setMasterContractApproval(
        address(this), // 授权主体:当前业务合约地址,不要填外部钱包地址
        address(tridentRouter), // 被授权的masterContract:Trident路由地址
        true, // 授权状态设为开启
        0, // 合约自身调用不需要签名,参数填0即可
        bytes32(0),
        bytes32(0)
    );

    ITridentRouter.ExactInputSingleParams memory exactInputSingleParams = ITridentRouter.ExactInputSingleParams(
        amountIn, 
        amountOutMinimum, 
        pool, 
        tokenIn, 
        data
    );
    // 原生币兑换时msg.value必须和amountIn严格相等
    tridentRouter.exactInputSingle{ value: msg.value }(exactInputSingleParams);
}

注意:如果是外部钱包直接调用Trident路由,不需要合约层的授权逻辑,只需要钱包提前完成两个授权:1. 给BentoBox开放对应ERC20的转账额度;2. 给TridentRouter开放BentoBox的masterContract操作权限即可。

内容的提问来源于stack exchange,提问作者Ivan Kral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:39:28