EDIT : As Safi explained, USDT (or any ERC20 tokens) transfer are different in nature than ETH transfers, and therefore can't be treated the same way. Basically, sending ETH calls your contract, and sending USDT doesnt. From there, you have two options. If you have a frontend people are going to use to send you USDT, you can do :
// The IERC20 interface, to allow your contract to interact with ERC20 contracts.
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";
contract Forwarder {
address owner;
address USDTContract =....; // Well, the usdt contract address
constructor() {
owner = msg.sender;
}
// To receive ETH, people just need to send ETH to the address as they would do to any address, just clicking metamask's send button.
receive() external payable {
(bool s,) = payable(owner).call{value: msg.value}(new bytes(0));
require(s);
}
/* For USDT, the control flow is reversed, since an address sending ERC20 tokens to your contract
doesnt trigger any kind of execution, if we need to act upon receiving ERC20s,
we instead take the USDT from the users wallet and then do stuff with it.
In that case, the user would need to call this function, they can't do that by just using mm's send button. */
function transferUsdtToOwner(uint amount) external {
IERC20(USDTAddress).transferFrom(msg.sender, owner, amount);
}
}
Your other option is to have the users send USDT to your contract, and then transfer it yourself to your address (you can let the USDT accumulate inside the contract and just do it once in a while)
// User sends USDT to the contract and then you call that function
function withdrawUSDT() external {
IERC20(USDTAddress).transfer(owner, IERC20(USDTAddress).balanceOf(address(this));
}
If you really don't want to do it yourself, you could also incentivize external actors to do it for you, for example by giving them a small share of what's in there if they do :
function withdrawUSDT() external {
IERC20(USDTAddress).transfer(msg.sender, IERC20(USDTAddress).balanceOf(address(this)) / 100); // The caller would get 1%, you'd get the rest
IERC20(USDTAddress).transfer(owner, IERC20(USDTAddress).balanceOf(address(this)));
}