I wrote the following code. I know it sends the ether from the contract balance but It doesn't allow me to send ether to the contract`s address.
How can I change the method so it will allow sending ether to the contract?
pragma solidity ^0.5.11;
contract MyFirstContract
{
function() external payable { }
function send(address payable _to, uint256 _value) public returns (bool)
{
require(_value <= address(this).balance);
_to.transfer(_value);
return true;
}
}
The reason it doesn't allow you to send ether to a contract's address could be there is no fallback function in that contract.
If you want to send ether to a contract without calling any of its functions, you need to have a fallback function in that contract to receive ether.
Add this function in the contract which you want to send ether to:
function () external payable {}
Here is a more detailed version: fallback
Related
I would like to make a function for receiving ERC20 in contract and after receiving ERC20 token it should transfer that ERC20 to another wallet.
the flow should be if a user uses that function first it should send that ERC20 to the contract and after that contract should forward that token to another wallet. I don't know where to start from
example transaction is this:
https://polygonscan.com/tx/0x88d85e4b746b65708a38b8f4c5d5bc0f73ff78e28868084eed565976b46df10e
The ERC-20 standard doesn't define how to notify a receiver contract about the incoming transfer. So you'll need to use either another standard (e.g. ERC-777) or build a custom notification hook.
Here's an example of such custom notification. It builds on top of the OpenZeppelin ERC-20 implementation, checks if the receiver is a contract - and if it is a contract, tries to call its onERC20Receive() function.
You can test it by deploying two separate contracts - MyToken and SomeReceiver - and then sending tokens from the deployer address to SomeReceiver. You can see that the ReceivedTokens event was emitted, as a result of invoking the function onERC20Receive when SomeReceiver received the tokens.
pragma solidity ^0.8.16;
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
constructor() ERC20("MyToken", "MyT") {
_mint(msg.sender, 1000 * 1e18);
}
function _afterTokenTransfer(address from, address to, uint256 amount) internal override {
if (to.code.length > 0) {
// token recipient is a contract, notify them
try IERC20Receiver(to).onERC20Receive(from, amount) returns (bool success) {
// the recipient returned a bool, TODO validate if they returned true
} catch {
// the notification failed (maybe they don't implement the `IERC20Receiver` interface?)
}
}
}
}
interface IERC20Receiver {
function onERC20Receive(address from, uint256 amount) external returns (bool);
}
contract SomeReceiver is IERC20Receiver {
event ReceivedTokens(address from, uint256 amount);
function onERC20Receive(address from, uint256 amount) external returns (bool) {
emit ReceivedTokens(from, amount);
return true;
}
}
For example I don't want to store ETH on Smart Contract but to the contract owner. Then how to implement withdrawal from the contract owner?
pragma solidity ^0.8.7;
contract WDfromContractOwner {
address public owner;
constructor() {
owner=msg.sender;
}
function deposit() external payable returns (bool) {
payable(owner).transfer(msg.value);
return true;
}
function withdrawal() external returns (bool) {
// Witdrawal from owner address....???
return true;
}
}
A smart contract is not able to pull ETH from an address (other than the address sending the ETH to the contract). The transfer needs to always be originated from and signed by the sender (in your case the owner).
However, it can pull tokens owned by an address. The sender (owner) needs to approve() the amount at first, interacting with the token contract from their address. Then your contract can invoke the token's transferFrom() function.
pragma solidity ^0.8;
interface IERC20 {
function transferFrom(address, address, uint256) external returns (bool);
}
contract WDfromContractOwner {
address public owner;
function withdrawToken() external {
// Only reachable from the mainnet.
// Transfers from other networks (such as Remix VM) will fail.
address mainnetUSDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
address receiver = msg.sender; // address of the user executing the `withdrawToken()`
uint256 amount = 5 * 1e6; // 5 USDT, 6 decimals
require(
// the `owner` needs to execute `approve()` on the token contract directly from the `owner` address
// so that the `WDfromContractOwner` contract can spend their tokens
IERC20(mainnetUSDT).transferFrom(owner, receiver, amount)
);
}
}
You can get the approved amount using web3.js:
const USDTAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
const ownerAddress = "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF";
// just the `balanceOf()` is sufficient in this case
const ABI = [
{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}
];
const USDTContract = new web3.eth.Contract(ABI, USDTAddress);
const approved = await USDTContract.methods.balanceOf(ownerAddress).call();
console.log(approved);
If you are already are transferring the funds to the owner each time an user deposit it should not be necessary, but if you want you could do it anyway, you have different options like passing the amount as a parameter, have a default or a minimum amount, etc, but for simplicity to withdraw all the funds just add this two lines in the function
(bool result,)= payable(owner).call{value: address(this).balance }("");
return result
I have an openZeppelin ERC721 NFT contract (MyNFTPrice.sol) and also a separate PaymentSplitter contract. My understanding is that these two contract need to be deployed separately. My question is, how do I send the price of minting from my NFT contract (MyNFTPrice.sol) to the PaymentSplitter contract? Currently, the price for minting an NFT resides in the MyNFTPrice.sol contract address.
MyNFTPrice.sol
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract MyNFTPrice is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor() public ERC721("MyNFTPrice", "NFTPRICE") {}
// Mint new NFT
function mintNFT(address recipient, string memory tokenURI) public payable {
require(msg.value >= 50000000000000000, "You need 0.05 ETH to mint the NFT");
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, tokenURI);
}
}
You can use the transfer() member of the address payable.
function mintNFT(address recipient, string memory tokenURI) public payable {
require(msg.value >= 50000000000000000, "You need 0.05 ETH to mint the NFT");
// effectively redirects the `msg.value` to the `0x123` address
payable(address(0x123)).transfer(msg.value);
// ... rest of your code
}
Replace the 0x123 to the real address of the PaymentSplitter.
You can also store the address in a variable and change it when you need to. In this case, it's recommended to use an authorization mechanism, such as the Ownable pattern, so that only an authorized sender can change the value.
Since the PaymentSplitter is a contract, it needs to contain the receive() or fallback() payable function. Otherwise the PaymentSplitter as the receiver would reject the incoming payment and effectively cause the whole mintNFT() transaction to revert.
contract PaymentSplitter {
receive() external payable {
// can be empty
}
}
I have a question and I try to google without much existence.
Let's take the example of this token:
1inch Token
So you can see that it has different tokens that people have sent to that address.
If I were the owner, how could I implement a function to withdraw all those tokens to my wallet?
Your contract can define the ERC20 interface function transfer(), and then execute this function on the external token contract.
pragma solidity ^0.8;
interface IERC20 {
function transfer(address _to, uint256 _amount) external returns (bool);
}
contract MyContract {
modifier onlyOwner {
require(msg.sender == address(0x123), 'Not authorized');
_;
}
function withdrawERC20Token(address _tokenContractAddress, uint256 _amount) external onlyOwner {
IERC20 token = IERC20(_tokenContractAddress);
// transfer the `_amount` of tokens (mind the decimals) from this contract address
// to the `msg.sender` - the caller of the `withdrawERC20Token()` function
bool success = token.transfer(msg.sender, _amount);
require(success, 'Could not withdraw');
}
}
Here is my code:
pragma solidity 0.8.6;
import "./Allowance.sol";
contract SharedWallet is Allowance {
event MoneySent(address indexed _beneficiary, uint _amount);
event MoneyReceived(address indexed _from, uint _amount);
function withdrawMoney(address payable _to, uint _amount) public ownerOrAllowed(_amount) {
require(_amount <= address(this).balance, "Contract doesn't own enough money");
if(!isOwner()) {
reduceAllowance(msg.sender, _amount);
}
emit MoneySent(_to, _amount);
_to.transfer(_amount);
}
function renounceOwnership() public override onlyOwner {
revert("can't renounceOwnership here"); //not possible with this smart contract
}
fallback () external payable {
emit MoneyReceived(msg.sender, msg.value);
}
}
Are you trying to send Ether to the contract as you deploy it? As I do not think you can do that easily. Well, there is a hacky way. Ethereum contract address is deterministic, i.e. knowing the creator's address and their nonce you can calculate the future address of your smart contract. And then send ETH to that address prior to deploying the contract.