This answer is 2 years late.. but I ran into this exact same problem today, and it surprised me how little information I could find.
The problem is that, calling usdt.transferFrom works with an external account, but does not work when calling from within a contract.
USDT did publish its contract code : https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#code
Which shows it uses the onlyPayloadSize modifier. According to another answer here: Validating msg.data.length and the article it references: https://blog.coinfabrik.com/smart-contract-short-address-attack-mitigation-failure/
It is possible for EVM to pad calls, causing msg.data.length to be longer than expected, thus failing the tx.
The most common solution seems to be just using Zeppelin's SafeERC20 library, like here in Aave's LendingPoolCore.sol, which passes arguments to transferFrom via abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
I tried it and it works perfectly. It costs a little bit more gas, my estimate is 20k-40k more, not a significant amount.
onlyPayloadSizeshould cause problems only if you're trying to invoke this function dynamically from another contract (i.e., viacall). – goodvibration Dec 23 '18 at 21:43transferortransferFrom? Do you have a transaction that failed? – Ismael Dec 24 '18 at 14:59