Currently, smart contracts are accepting ETH as the payment token.
Is it possible to only accept USDT for a smart contract instead? Are there simple examples for this?
Thank you.
Currently, smart contracts are accepting ETH as the payment token.
Is it possible to only accept USDT for a smart contract instead? Are there simple examples for this?
Thank you.
Yes, you can send USDT to your smart contract . If you want to withdraw from smart contract to your wallet , please set up USDT address on Ethereum inside constructor of your smart contract and get instance of ERC20 .
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
import "./IERC20.sol" // import IERC20.sol from openzeppelin library
contract StoreContract {
IERC20 public usdt;
constructor (address _usdtAddress) {
usdt = IERC20(_usdtAddress);
}
receive() external payable{}
function deposit() external payable{
}
function withdraw() external{
usdt.transfer(msg.sender,amount);
}
}
Interesting!
I guess i'll go play around abit with that snippet.
Thank you so much!
If I can just give an advice...
Payable keyword and fallback function is not needed if the contract only has to receive erc20 tokens. Leaving there the fallback can cause a lost of BNB
Also, here is missing the third input: the amount
Sorry, usdt.transfer(msg.sender,amount)
I am facing a problem with exceeding allowance. I believe i have to increase said allowance somewhere within my contract, is that right?
Lets say
/**
* @dev Determines how usdt is stored/forwarded on purchases.
*/
function _forwardFunds(address recipient, uint256 amount) internal {
//reset allowance to 0
usdt.safeApprove(_token, _msgSender(), 0);
//increase allowance to transfer amount
usdt.safeIncreaseAllowance(_token, _msgSender(), amount);
//transfer usdt from msg sender to recipient
usdt.transferFrom(_msgSender(), recipient, amount);
//remove allowance of transfer amount
usdt.safeDecreaseAllowance(_token, recipient, amount);
}
is this how it works?
Or should i Deposit USDT into the contract, then using the contract to transfer USDT to recipient?
Yes mate, it is possible. You can. Simply accept an instance of type USDT contract you wish to accept or rather accept an address type and wrap it in IERC20 instance then use it in the required function. You might also need to inform your user that you are not accepting ETH, or better still make the function non-payable and reject any unsolicited ETH in the fallback but be mindful that your contract can still accept ETHER if another contract sets your contract address as the beneficiary in a selfdestruct action in their contract. But do not worry much if receiving ether would not cause a devastating effect on your contract.
//Pragma solidity ^0.7.0;
interface IERC20 {
//Some interface non-implemented functions here
}
contract AcceptUSDTOnly {
IERC20 accepted;
constructor (IERC20 instanceAddress) {
accepted = instanceAddress;
}
receive() external payable {
//not accepting unsolicited ether
revert("Reason")
}
function buySomeStuff() public {
//use IERC20 instance to perform the exchange here
}
}
If you're calling usdt.safeApprove for instance, the msg.sender would be your contract and not your user because you're making an external call. So in this, case, you have no usdt balance in the usdt contract you're calling hence fails.
I see,
The thing im doing is trying to modify the Crowdsale Contract to only accept USDT.
So in this case i should be depositing the USDT into the Crowdsale Contract first, then from Crowdsale Contract to transfer to the actual wallet address?
You have to think it twice. Assume I am the buyer and I need to buy from your contract using usdt . You need to have a way of extracting the usdt from me which will as well alert your contract that I have sent some amount. You might want to consider a manual method where you verify manually that I have paid some usdt and then send me some token if you can't find a way to automate the process or you just gotta make some external calls to the usdt contract.
Hmm, I see.
I will go and experiment more. Thank you!
I have been trying a few methods,
I think this should have been the best method as it transfers from Buyer to Funds Wallet
Method 1
/**
* @dev Determines how usdt is stored/forwarded on purchases.
*/
function _forwardFunds(uint256 amount) internal {
usdt.increaseAllowance(address(this), amount);
usdt.transferFrom(_msgSender(), _wallet, amount);
usdt.decreaseAllowance(address(this), amount);
}
But i always face with this error "ERC20: transfer amount exceeds allowance".
I have also tried
Method 2
/**
* @dev Determines how usdt is stored/forwarded on purchases.
*/
function _forwardFunds(uint256 amount) internal {
usdt.approve(address(this), 0);
usdt.increaseAllowance(address(this), amount);
usdt.transfer(address(this), amount);
usdt.transferFrom(address(this), recipient, amount);
usdt.decreaseAllowance(address(this), amount);
}
This method works IF i transfer some USDT in advance into the Crowdsale.
And that is because im transferring from Crowdsale > Wallet, Buyer > Crowdsale.
I believe only after the function has ended, then the buyer's USDT is transferred to the Crowdsale right?
EDIT : I tried splitting Approve function by itself before making a purchase. It still have the same exceed allowance error.
EDIT 2 : I found out if i wish to do approve and transferFrom all within one tx, i need the token to have a ApproveAndCall function. Which i cannot confirm USDT has, so i believe method 1 is not possible anymore. I shall move forward with separating everything.
Well, I found out firstly,
The Front End has to call the function to Approve the allowance for the contract to use.
This is probably not what we were looking for, so I guess we'll go back to use the Native Token instead.
Thanks everybody for the help!
For others who are looking for how this could or should be done.
Use frontend to approve Smart Contract allowance, then just use transferFrom within the Smart Contract as per normal.
I tried using Truffle and Hardhat but I have no idea how to call approve.
So just having a member IERC20 accepted;
makes my contract able to get usdt? just using the fallback function?