Transfer function not working as expected in solidity - blockchain

Considering below code
mapping (address => uint256) public balanceOf;
event Transfer(address indexed from, address indexed to, uint256 value);
function _transfer(address _from, address _to, uint _value) internal {
require(_to != 0x0);
require(balanceOf[_from] >= _value);
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
Transfer(_from, _to, _value);
}
function sell(uint256 amount) public {
require(this.balance >= amount * sellPrice);
_transfer(msg.sender, this, amount);
msg.sender.transfer(amount * sellPrice);
}
function sendTokens(address _to, uint value) public {
_transfer(msg.sender,_to,value);
msg.sender.transfer(value * sellPrice);
}
function buy() payable public {
uint amount = (msg.value / buyPrice) * 1 wei;
_transfer(this, msg.sender, amount);
}
Here sell() and buy() function sends/receive tokens to/from contract but when function with almost same signature sendTokens() is called it is not able to send or are sending 0 tokens. Contract also has ethers and tokens. But it always consider tokens to send and receive. But sendTokens is not behaving same with almost same code.
Also I have an another question related to this. Every account has ethers and multiple tokens. Then how will it identify that here this specific tokens needs to be send or here ether is to be send and not any tokens.
Can anyone help. Thanks in advance.

Well there is no correction in the code. Perhaps Metamask and remix is not supporting this type of transaction at this moment. When I call this method from Web3js it worked. So couldn't find the exact reason but yes it worked at end.

Related

Is payble keyword neccessary even if I am not taking any ether/matic?

function sendGift(uint256 _mintAmount,address recipient) public payable {
uint256 supply = totalSupply();
require(!paused);
require(_mintAmount > 0);
require(_mintAmount <= maxMintAmount);
require(supply + _mintAmount<= availableSupplyForSale);
//require(_amount >= cost * _mintAmount);
require(coinToken.allowance(msg.sender,address(this))>=cost * _mintAmount);
coinToken.transferFrom(msg.sender, address(this),cost * _mintAmount);
if(supply<currentSupply){
for (uint256 i = 1; i <= _mintAmount; i++) {
_safeMint(recipient, supply + i);
}
}
else{
uint256[] memory tokenIds = walletOfOwner(address(this));
for(uint256 i=1;i<=_mintAmount;i++)
transferFrom(address(this),recipient,tokenIds[i]);
}
}
Do I need to use payable here? Contract does not take any matic. It only takes custom token as payment .
(bool os, ) = payable(admin).call{value: address(this).balance}("");
require(os);
Also since I am not taking any matic, will this above line necessary for withdraw assets from contract as an owner? I have a sense that this above line only is useful to withdraw eth/polygon.
I am a new blockchain kid. Please help.
The payable modifier of a function is required when your function accepts native tokens (ETH, BNB, MATIC, ... depending on the network).
So in this case, you can safely remove it from the function header.
// removed `payable`
function sendGift(uint256 _mintAmount,address recipient) public {
The low-level .call() also doesn't require using payable to send native tokens.
payable(admin).call{value: address(this).balance}("");
However, if you used the high-level .transfer(), then you'd need to cast the admin variable type address to its extension type address payable using the typecasting function.
// will not work as it's type `address`
admin.transfer(address(this).balance);
// need to cast type `address` to type `address payable`
payable(admin).transfer(address(this).balance);
In order to withdraw tokens from your contract address, you need to invoke the transfer() function (defined in the ERC-20 standard) on the token contract. Do not confuse it with the native transfer() function of address payable, these are two separate things, just with the same name.
interface IERC20 {
function transfer(address, uint256) external returns (bool);
}
contract MyContract {
function withdrawToken() {
IERC20(tokenContractAddress).transfer(recipient, amount);
}
}

How to use transfer function in solidity

I created smart contract to transfer ETH from one account to another, ETH deduction occurs but send to other address(which is not specified). Please help me to resolve this problem.
//SPDX-License-Identifier:MIT
pragma solidity ^0.8.12;
contract ETH{
address public buyer;
uint public amt;
address public seller;
constructor(){
seller = msg.sender;
}
function add(address payable _buyer) payable public{
buyer = _buyer;
payable(buyer).transfer(amt);
}
function bal() view public returns(uint){
return buyer.balance;
}
function s() payable public returns(uint){
return msg.value;
}
}
The default value of amt is 0 and your code does not set this property (to a non-zero value) anywhere.
Which effectively makes your .transfer(amt) function to send 0 ETH to the buyer and keep all the ETH, that you sent along with the transaction, in the contract.
If you want to redirect the sent amount, there's the msg.value global variable, which reflects the current value sent with the transaction.
payable(buyer).transfer(msg.value);

What is the usage of Context.sol within ERC-20?

When releasing the ERC-20 token,
OZ(OpenZeppelin)'s util Context.sol is inherited.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/*
* #dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
I read that when using a meta-transaction solution such as EIP-2771, Context.sol is useful.
https://forum.openzeppelin.com/t/help-understanding-contract-context/10579
function _msgSender() internal view virtual override returns (address sender) {
if (isTrustedForwarder(msg.sender)) {
// The assembly code is more direct than the Solidity version using `abi.decode`.
assembly { sender := shr(96, calldataload(sub(calldatasize(), 20))) }
} else {
return super._msgSender();
}
}
But in the case of ERC-20, why shoud I use Context.sol's _msgSender()?
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
Doesn't make it more secure?
What is the usage of Context.sol within ERC-20?
Thank you in advance.
Context is needed to implement metatransactions, or gas free transactions for token transfers.
More about Context in Gas Station Network documentation.
If you do not plan to support this feature (hint: no one does today) you do not need to Context.

Refund all addresses entered on solidity contract

I have a problem related to refund the users entered inside the solidity contract. I don't, have any idea if is possible iterate all the players of my contract and refund all of them with all the balance.I read in some tutorials, iterate inside the solidity contract cost a lot of gas depends of the numer of iterations.
contract Lottery{
address payable public manager;
string public name; // short name (up to 32 bytes)
address [] players;
uint256 nTickets;
address winner;
bool enable;
uint256 minimunContribution;
mapping(address => uint) public balances;
constructor (string memory LotteryName, uint minimun, address payable creator) public {
manager = creator;
name = LotteryName;
winner = address(0);
enable = true;
minimunContribution = minimun;
}
modifier restricted() {
require(msg.sender == manager, "Access forbidden");
_;
}
function enterInToLottery() public payable {
require(msg.value > minimunContribution && enable == true, "Insufficient funds to allow transfer");
players.push(msg.sender);
balances[msg.sender] += msg.value;
nTickets++;
}
//this function refund
function paybackEther(bool newfinished) public restricted {
enable = !newfinished;
selfdestruct(msg.sender);
}}
Thanks in advance to all.
Yes that can be problematic as it will use a lot of gas and may even hit limits. To solve this it is better to allow the users to withdraw the balance themselves, so they pay for the gas. Or in fact you can allow anybody to make that call. So you can offer a call refund(account:uint256) which transfers the balance (if any) to given account. Note that this would not be using msg.sender, so that anybody (including the admin) can do this transfer.
Keep in mind they need to know that they have a balance, so make sure you're emitting an event or similar. Also provide a balanceOf(address) call so they can check.
Hope this makes sense & works for you.

Could somebody please explain in detail what this Ethereum contract is doing?

I am new to blockchain technology and trying to understand somethings(Etheruem, Truffle, DApps etc.) here and there from the internet.
From Ethereum official website,
Create a cryptocurrency contract in Ethereum
I am trying to specifically understand these functions
approve(address _spender, uint _value) returns (bool success) {...}
approveAndCall(address _spender, uint _value, bytes _extraData) returns (bool success) {...}
transferFrom(address _from, address _to, uint _value) returns (bool success) {...}
and lastly this function() {throw;}
This contract code
contract tokenRecipient {
function receiveApproval(address _from, uint _value, address _token, bytes _extraData);
}
and this declaration mapping (address => mapping (address => uint) ) public allowance;
First function basically takes address to where coin is to send and the value to be sent and return boolean value. Other function is for transfer value and takes sender and reciever address and returns again bookean value for success or failure.
I posted this question on Ethereum Stackchange and got the answer. Follow the comments also.
How does a token contract work?