問題
使用openzeppelin
的IERC20
封裝USDT
,在合約中使用 USDTtransfer
方法失敗!
原因
這是因為 USDT 的合約實現不是標準的ERC20
代幣的實現,openzeppelin
的ERC20
的transfer
協議是這樣的
function transfer(address to, uint256 amount) external returns (bool);
而 USDT 的transfer
方法是這樣的
function transfer(address to, uint value) public;
USDT的方法沒有返回 bool 值,所以用openzeppelin
的IERC20
的介面去包裝USDT
使用transfer
方法會失敗。
解決方案
使用openzeppelin
提供的SafeERC20
提供的safeTransfer
方法,因為有很多其他代幣或者 solidity 版本的問題,不是按照標準協議實現的,所以需要對ERC20
代幣的transfer
方法做一些安全處理。
具體步驟是:
匯入
SafeERC20
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
使用
SafeERC20
using SafeERC20 for IERC20;
使用
safeTransfer
方法_usdt.safeTransfer(to, amount);
完整程式碼
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract USDTTransfer {
address private _usdtAddr =
address(0xDbf8Bf15bb3438b7410d8f009d652508ffA97C7B);
constructor() {}
IERC20 private _usdt;
using SafeERC20 for IERC20;
function safeTransferUSDT(address to, uint256 amount)
public
returns (bool)
{
_usdt = IERC20(_usdtAddr);
_usdt.safeTransfer(to, amount);
return true;
}
}