is there a ERC/IERC20 function or util that ensures received payment is denominated in a specific token?
receive() external payable virtual {
IERC20 token = IERC20(address(0x123...789));
require(
paymentToken == MYtoken,
"Payment Must be MY token"
);
emit PaymentReceived(_msgSender(), msg.value);
The receive() function is for your contract to accept ETH. Or generally - the native token of the network where the contract is deployed (BNB on BSC network, TRX on Tron network, ...).
But if your contract address receives a standard ERC-20 token, it doesn't get notified in any way.
Except for cases, where the token contract specifically calls the receiver to let them know about the transfer (as defined for example in the EIP-777 tokensReceived() hook). But this hook needs to be defined in the token contract in the first place, so that you can make use of it in your receiver contract. If it's not in the token contract, then your contract can't get directly notified about received tokens.
Related
When a user sends some Ether to a smart contract/dApp address, is there a way I can access that transaction in my smart contract? Like a built-in method that's invoked, that I can add some code to?
My ideal work flow, if it's possible:
User sends Ether to my dApp address.
A function is invoked in my smart contract code.
Within that function, I can create some logic, like add their address to some state, etc.
Ideally, I want to avoid a user having to invoke a particular public function of the contract, but instead just send Ether to the dApp address.
If the user has to invoke a particular function, I have to start thinking about services like MEW, or I have to build a web2 frontend app that integrates with the MetaMask browser extension or something. This seems like a lot of work, but is this the way it has to be?
There is the receive() special function that gets executed when you send ETH to the contract address and not specify any function to execute (i.e. the data field of the transaction is empty).
You can get the sender address through the msg.sender global variable and the amount through msg.value.
pragma solidity ^0.8;
contract MyContract {
mapping (address => uint256) contributions;
receive() external payable {
contributions[msg.sender] += 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 :)
Learning Solidity along with token development.
I'm having a hard time understanding how tokens with multiple smart contracts interact with each other.
I've read through other tokens with multiple contracts on GitHub and reviewed contracts on OpenZeppelin but they all appear somewhat orphaned.
Let's say we developed a token that has a supply and tracks wallet address to amount using a map. The contract is released and is given an address. Admin or privilege methods are protected via owner address validation. Then we release a second contract that needs to make apply a fee for transactions.
How does the second (token transaction fees) contract interact with the data stored on the first (token contract)? Does the second contract need to also verify ownership?
Any contract on Ethereum can interact with any other contract by using Interfaces. You can call methods from the second contract on the first contract for an ERC20 token as below:
Define ERC20 Interface
interface ERC20 {
function balanceOf(address account) external view returns (uint256);
}
Use the interface and token contract address to call methods on the first contract:
ERC20(tokenContractAddress).balanceOf(0xabcd....);
The similar approach can be used for any contracts
I want to create a smart contract which people can transfer tokens without ether in their wallet.
Suppose A want to transfer ERC20 tokens to B, but he does not have ether in his wallet.
Does third party C can send the transaction for A and therefore pay the gas? Is it possible to create a function in the contract for this usgae?
I have searched online for a soloution and could not find one.
This is a key issue of Ethereum dApp development, but also of tokens. Here is a very old thread on Ethereum Stack Exchange, and also this one.
There are 2 options with their pros and cons:
Use signatures
Every function in your smart contract must have signature parameter.
People who want to interact with the smart contract must sign the function parameters with their account's private key and send it to the smart contract owner (via any communication channel).
The owner then submits the parameters along with the signature to the blockchain, paying for gas. The signature guarantees that the message was approved by the user.
Refund used gas at the end of the transaction. A modifier refundGasCost can be used for this (see below).
But (1) is really hard to apply to token transfers where you just don't know who uses the token and (2) does not really address the issue.
There is a lot happening recently, there is this blog post about How to save your Ethereum Dapp users from paying gas for transactions, and since you ask about tokens, there is an ERC that suggests to Pay transfers in tokens instead of gas, in one transaction which would be nice if you have tokens but no ETH.
I hope this helps.
Exactly this case is already defined in the ERC20 standard. Its this function:
function transferFrom(address from, address to, uint tokens) public returns (bool success);
But before party C could use it and send tokens from A to B, A would have to approve C to do this via the following function, which is also defined in the ERC20 standard:
function approve(address spender, uint tokens) public returns (bool success);
No, in a standard ERC20 token contract, the token holder must initiate at least one transaction (to call transfer() or approve()), and a transaction must always be paid for by its initiator.