Не все solidity контракты строго соблюдают erc20 стандарт.
Есть исключение, которое не видно на уровне взаимодействия с abi.
Это исключение становится видно тогда, когда смарт-контракт размещен в блокчейне, а вывести токены нельзя.
Имя этому токену usdt. Прелесть в том, что erc20.transfer должен вернуть bool, но usdt думает иначе, поэтому типичный erc20.transfer будет тихо фейлиться без объяснения причин. В tenderly выглядит как REVERT
.0x()usdt 0xa9059cbbfunction transfer(address _to, uint _value) public whenNotPaused {usdc 0xa9059cbbfunction transfer(address to, uint256 value) external returns (bool) {Чтобы такое не повторялось, используется safetransfer библиотека для solidity, чтобы такие случаи не хоронили нестандартные токены на контракте.
Реализации safetransfer:
- openzeppelin SafeERC20
- Uniswap V3 TransferHelper (docs)
- Uniswap V3 (solidity)