I wanted to ask if its possible to have a USDT tokens (like the standard smart contract's balance in Ether) inside my smart contract, and if it was possible to than swap it with the Ether inside the smart contract's balance (if possible using Uniswap; swapping both from ETH to USDT and viceversa).
Thanks.
Yes, it is entirely possible to store ERC20 token in any contract, since the balance of ERC20 token is only defined as a mapping of mapping(address => uint256) in the ERC20 contract.
However, since transferring ERC20 requires either you as the owner or you having the approval to transfer, you will need to give yourself, or the address executing transactions, allowance to transfer the ERC20 "stored" in the contract address, or otherwise, the ERC20 token will be stuck inside the contract.
For the swapping part, you can look into the interfaces of Uniswap and have your smart contract call to Uniswap for the swap.
Related
I am a newbie in the blockchain technology and I have question.
I just deployed an Ethereum smart contract to the Rinkeby testnet network and minted a few NFTs. When checking my contract address on rinkeby.etherscan.io I can see the smart contract's balance.
The question is, how can I transfer these ethereum in the smart contract balance to my wallet. Since I am the owner I should receive these ETH somehow to my metamask wallet no?
Smart contract includes the following function
// This will transfer the remaining contract balance to the owner.
// Do not remove this otherwise you will not be able to withdraw the funds.
(bool os, ) = payable(owner()).call{value: address(this).balance}('');
require(os);
}```
so it should be possible...
To be able to withdraw the funds from your contract to a wallet you own you must implement a withdraw method like so:
address public primary_wallet = YOUR_WALLET_ADDRESS
function withdraw() public payable onlyOwner {
(bool os,)= payable(primary_wallet).call{value:address(this).balance}("");
require(os);
}
You will also need to make sure that you import import "#openzeppelin/contracts/access/Ownable.sol"; to use the onlyOwner modifier. This allows only the person who deployed the contract to withdraw the funds and nobody else. This is a must. Hope this helps.
Per your current implementation, you need to manually invoke the withdraw() function from the owner address each time you want to withdraw ETH from the contract.
Your mint functions accept ETH and keep it on the contract address.
If you want to transfer the funds to the owner each time a mint is performed, you need to explicitly invoke the transfer from each of the mint functions. Example:
function mint(uint256 _mintAmount) public payable mintCompliance(_mintAmount) mintPriceCompliance(_mintAmount) {
require(!paused, 'The contract is paused!');
_safeMint(_msgSender(), _mintAmount);
// auto transfer received funds to the owner
payable(owner()).transfer(msg.value);
}
I am following a tutorial for a crowdfunding smart contract that accepts a token from users.
I have developed a simple ERC20 token, then I deploy the crowdfunding smart contract giving the address of the ERC20 token as the token accepted from users.
I would like to use the same smart contract with ethers. In other words, I would like people to fund the smart contract with ethers (using ganache and remix, my 10 users have 100 ethers each). Therefore, I need to deploy the smart contract giving the ethereum token address. What is the ether's address?
I am working with remix and ganache under web3 provider.
The native token of any EVM network (in your case Ether) does not have any address.
In Solidity, you can:
Accept ETH with the payable function modifier
Validate the amount sent by the user stored in the msg.value global property. The variable is read-only, the sender chooses how much they send and your contract can only validate that.
Send ETH with the native .transfer() function of address payable (extension of address) type. Do not confuse with the ERC20 custom transfer() function - these are two separate functions even though they have the same name.
pragma solidity ^0.8;
contract MyContract {
address owner = address(0x123);
// `payable` modifier allows the function to accept ETH
function foo() external payable {
// validate that the received amount is 1e18 wei (1 ETH)
require(msg.value == 1e18);
// typecast `address` variable (name `owner`)
// to `address payable` and effectively redirect the received value
// with the native `transfer()` function of the `address payable` type
payable(owner).transfer(msg.value);
}
}
If you need to work with approvals and other ERC-20 features, many contracts use WETH (Wrapped Ether) token that uses tokenomics supposed to maintain the same WETH price as ETH has, instead of using the regular ETH. Its production address depends on the network where its deployed. For example:
Ethereum: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Polygon: 0x7ceb23fd6bc0add59e62ac25578270cff1b9f619
My ultimate purpose is to swap some tokens across pancakeswap babyswap apeswap atomicly. So I build a contract(called ContractA) to run a bunch of swaps in a transaction. I transfer some USDT token into ContractA. But ContractA is not approved to transfers USDT by the USDT contract.
I known how to approve Metamask address to transfer USDT, but how to do it for a Contract?
In order to control an ERC20 token from a smart contract, first you need to create an instance of it. To do that, first you need to import ERC20 to your contract, and then just create an ERC20 type function giving it the token address you want to manage. It would be something like this:
// Some code...
import "#openzeppelin/contract/token/ERC20/ERC20.sol";
// Some more code...
contract exampleContract {
// Example of an ERC20 token instance
ERC20 USDTToken = ERC20("USDT Contract Address Here");
// Approve USDT
USDTToken.approve(address(this), _amount);
}
Then you will be able to manage the token, always following the ERC20 standard, as you want.
Hope you find this information useful :)
How do I make a existing running erc20 to prevent some holders from transacting?
I am trying to do a staking feature. Can I write a new contract to control the existing erc20 contract?
Logic that would affect a token holder's ability to transfer (or have a party transferFrom on the holders behalf) must be written into the contract if you want token transfers to be halted within the contract itself. Therefore, if you already have a contract deployed you would have to deploy a new ERC20 contract that has the logic - if you want the staking mechanism to be within the same contract. Then you would have to transfer balances from the previous version of the contract to the newly deployed contract. While possible, it would incur a gas expense to replicate the contract state. You could have your token holders pay this gas cost by having some sort of mint or recover function that would read the old contract balance for an address, create the balance on the new contract, and then mark the balance as transferred.
Alternatively, to your second question, you could facilitate the staking with an additional contract that users would set an allowance to within the ERC20 contract. Then, users could interact with something like a stake function on this new staking contract. The staking contract would use the transferFrom ERC20 function to transfer tokens from the owner to the staking contract's address after incrementing the user's staked token amount within the staking contract. This would record the holder's staking "credit" and tie the tokens up by transferring their ownership to the staking contract. Users could then unstake which would decrement the user's staked token amount and transfer the tokens back from the staking contract's address to the token holder's address. This type of approach has more moving pieces but could be a more flexible step while developing the mechanism as you can deploy new versions of the staking contract without having to redeploy the ERC20 contract or transfer balances. Users would be able to transfer like normal throughout multiple versions of the staking contract and extracting tokens from previous versions of the staking contracts would be gas-efficient.
This question is a little conceptual, so hopefully this picture will help clear up my misunderstanding.
Image there is a crowdsale smart contract deployed on address 0x2. A User at address 0x01 buys a token.
Here is my understanding of what happens:
The crowdsale contract (# address: 0x2) accepts ether from the user account (# address: 0x1)
The crowdsale contract stores 0x1 as having purchased a token (important: this information is stored in the smart contract #address 0x2)
Now my Question: If 0x1 is a user account (and not a smart contract) there is no code at address 0x1. I thought a user account just consisted of an address + ether associated with the address, how can it also store the fact that 0x1 owns an ERC20 token? For example, I can login to MetaMask and (before clicking the "add token" option) MetaMask can see that I have a token... how is this possible?
Every ERC20 contract has the following function:
function balanceOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
Your wallet just calls this function from the known token contracts with your address. Since it's a view function it doesn't cost any gas.
I recon most ERC20 token get added rather quickly to a wallet like Metamask or MEW. But if your balance doesn't automatically show, you can add the contract address manually (in MEW at least, not sure about Metamask) and it will show up afterwards.
In solidity there are two ways to get the address of the person who sent the transaction
tx.origin
msg.sender
In your example, in the method inside ERC20 Token.sol, the value tx.origin will be 0x1 and msg.sender will be 0x2
So to answer your question, how does the ERC20 token know about 0x2 is: it depends on how the token contract is written and whether it uses tx.origin or msg.sender. I would imagine it uses msg.sender, because that is the more prevalent one.
If it does use msg.sender you can still make the crowdsale contract work by first buying the tokens and then immediatelly transfering the tokens from the crowdsale contract to the caller.
For more information, refer to What's the difference between 'msg.sender' and 'tx.origin'?
how can it also store the fact that 0x1 owns an ERC20 token?
Token transfers, or transfers in accounting in general, are kept in a ledger. In this case, the ledger is ERC-20 smart contract that internally keeps balances who owns and what in its balances mapping. Or, the smart contract manage the storage (EVM SSTORE instructions) where the records of ownership are kept.
Note that some other blockchains, like Telos and EOS (and mayne Solana) might be opposite and there the storage is maintained on the user account (user account has associated RAM and tables for any token user owns).