Solidity decimal values - solidity

I need put a minimum value of user can pay, and this value must be e.g 0.5 BNB.
But I don't know how I can do this.
uint comissionFee = 5; // 5 will represent 0,5
uint256 minimunPay = comissionFee*100/1000;
But return 0
pragma solidity ^0.8.4;
function payFees() public payable {
require(msg.value >= 0.5); // <-- not compatible with uint256
(bool success,) = owner.call{value: msg.value}("");
require(success, "Failed to send money");
}

Firstly, there are no double numbers in solidity lang.
All calculations are done with whole numbers. To solve this issue, all tokens on Ethereum/Binance Chain consider some big decimal number as a threshold of double and ceil parts.
In ERC20 tokens this number is calculated based on the decimal field of the contract: 10^decimal.
For the native token ETH/BNB, there is a fixed decimal equal to 18.
Your code could be fixed this way:
pragma solidity ^0.8.4;
function payFees() public payable {
require(msg.value >= 0.5 ether);
(bool success,) = owner.call{value: msg.value}("");
require(success, "Failed to send money");
}
OR
pragma solidity ^0.8.4;
function payFees() public payable {
require(msg.value >= 5 * 10**17);
(bool success,) = owner.call{value: msg.value}("");
require(success, "Failed to send money");
}

In solidity msg.value is not represented as Ether but as Wei a smaller denomination of ether you can think of it as ether with 18 decimals. Example:
1 ether is 1000000000000000000 Wei. Note that this applies for most chains to my knowledge BSC is also based on an 18 decimal system so 0.5BNB would be 500000000000000000 Wei this way you can check decimal values like this:
pragma solidity ^0.8.4;
function payFees() public payable {
require(msg.value >= 500000000000000000);
(bool success,) = owner.call{value: msg.value}("");
require(success, "Failed to send money");
}
Or:
pragma solidity ^0.8.4;
function payFees() public payable {
require(msg.value >= 0.5 ether);
(bool success,) = owner.call{value: msg.value}("");
require(success, "Failed to send money");
}
You can also take a look at this for a better demonstration of how this works.

Solidity works with integers. Why are there no decimal numbers in Solidity?
Uniswap created FixedPoint. you can use this function:
function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {
require(denominator > 0, 'FixedPoint::fraction: division by zero');
if (numerator == 0) return FixedPoint.uq112x112(0);
if (numerator <= uint144(-1)) {
uint256 result = (numerator << RESOLUTION) / denominator;
require(result <= uint224(-1), 'FixedPoint::fraction: overflow');
return uq112x112(uint224(result));
} else {
uint256 result = FullMath.mulDiv(numerator, Q112, denominator);
require(result <= uint224(-1), 'FixedPoint::fraction: overflow');
return uq112x112(uint224(result));
}
}
in your solidity code:
using FixedPoint for *;
FixedPoint.fraction(numeratorValue,denominatorValue)

Related

problem in crowdfunding contract: ParserError: Expected primary expression

I am with a code but I have this problem:
ParserError: Expected primary expression. --> contracts/Crowfunding.sol/crowfundingstampe.sol:35:2: | 35 | } | ^
the code is:
> SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
contract Crowfunding {
uint256 public fundingGoal; //the target amount of funds that must be raised for the campaign to be considered successful
uint256 public deadline; // the deadline by which contributions must be received
uint256 public amountRaised; // the total amount of funds raised so far
mapping (address => uint256) public contributions; // tracks the amount contributed by each individual.
address [] public suppliers; //an array that keeps track of the addresses of all suppliers who have contributed to the campaign
bool public funded;
uint256 public fundsReturned;
constructor(uint256 _fundingGoal, uint256 _deadline) public {
fundingGoal = _fundingGoal;
deadline = _deadline;
}
function contribute() public payable {
require(msg.value > 0, "You must contribute a positive amount.");
require(now <= deadline, "The deadline for contributions has passed.");
contributions[msg.sender] += msg.value;
amountRaised += msg.value;
backers.push(msg.sender);
}
function returnFunds() public {
require(now > deadline, "The deadline for contributions has not passed yet.");
require(fundsReturned == 0, "The funds have already been returned.");
for (uint256 i = 0; i < backers.length; i++) {
backers[i].transfer(contributions[backers[i]]);
}
>
to compile but it pop o that error
First of all was missing array backers, two brackets } , keyword now deprecated, instead use block.timestamp, and in for() loop backers[i] must be payable.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Crowfunding {
uint256 public fundingGoal; //the target amount of funds that must be raised for
the campaign to be considered successful
uint256 public deadline; // the deadline by which contributions must be received
uint256 public amountRaised; // the total amount of funds raised so far
mapping (address => uint256) public contributions; // tracks the amount
contributed by each individual.
address [] public suppliers; //an array that keeps track of the addresses of all
suppliers who have contributed to the campaign
bool public funded;
uint256 public fundsReturned;
address[] public backers;
constructor(uint256 _fundingGoal, uint256 _deadline) {
fundingGoal = _fundingGoal;
deadline = _deadline;
}
function contribute() public payable {
require(msg.value > 0, "You must contribute a positive amount.");
require(block.timestamp <= deadline, "The deadline for contributions has
passed.");
contributions[msg.sender] += msg.value;
amountRaised += msg.value;
backers.push(msg.sender);
}
function returnFunds() public {
require(block.timestamp > deadline, "The deadline for contributions has not
passed yet.");
require(fundsReturned == 0, "The funds have already been returned.");
for (uint256 i = 0; i < backers.length; i++) {
payable(backers[i]).transfer(contributions[backers[i]]);
}
}
}

Transfer Eth through smart contract to other account?

In the below code eth will be transferred in the form of Wei by default, but I want the amount will transfer in the form of Ether, how can I do that?
function (uint amount) public payable {
someaddress.transfer(amount);
}
Wei is the smallest unit of Ether, specifically 1 ETH == 1,000,000,000,000,000,000 (or 1e18) wei.
The transfer() function always accepts the amount in wei. So if you want to pass just 1 as the input param, meaning that you want to send 1 full ETH, you can multiply the value by 1e18 effectively converting ETH to wei.
function (uint ethAmount) public payable {
uint weiAmount = ethAmount * 1e18;
someaddress.transfer(weiAmount);
}
Note: There's also the ether global unit, but in the current Solidity version (0.8), this can be used only in combination with number literals - not with variables.
uint weiAmount = 1 ether; // ok
uint weiAmount = ethAmount ether; // syntax error

Solidity Error by deploying a contract : cannot estimate gas; transaction may fail or may require manual gas limit

I have the following contract in Solidity:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/utils/Strings.sol";
contract MyContract is ERC1155, Ownable {
string public name;
string public symbol;
uint256 public mintPrice;
uint256 public totalSupply;
uint256 public maxSupply;
address public withdrawWallet;
constructor(string memory _name, string memory _symbol) payable ERC1155("https://ipfs.io/ipfs/QmQq3kLMG8fkikYqjrBST2inxTk9sYpcAn274e14sdfgj/") {
name = _name;
symbol = _symbol;
mintPrice = 0.002 ether;
totalSupply = 0;
maxSupply = 10000;
withdrawWallet = msg.sender;
}
function mintOwner(uint256 _amount) public onlyOwner {
require(totalSupply + _amount <= maxSupply, 'Sold out');
_mint(msg.sender, 0, _amount, "");
totalSupply = totalSupply + _amount;
}
function mint(uint256 _amount) public payable {
require(msg.value == _amount * mintPrice, 'wrong mint value');
require(totalSupply + _amount <= maxSupply, 'Sold out');
_mint(msg.sender, 0, _amount, "");
totalSupply = totalSupply + _amount;
}
function setURI(string memory newuri) public onlyOwner {
_setURI(newuri);
}
function withdraw() external onlyOwner {
(bool success,) = withdrawWallet.call{value : address(this).balance}('');
require(success, 'withdraw failed');
}
}
It works fine and I can deploy it until I add the mint() function with price requirement:
function mint(uint256 _amount) public payable {
require(msg.value == _amount * mintPrice, 'wrong mint value');
require(totalSupply + _amount <= maxSupply, 'Sold out');
_mint(msg.sender, 0, _amount, "");
totalSupply = totalSupply + _amount;
}
After that I get the following error message:
Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (reason="execution reverted: wrong mint value", method="estimateGas", transaction={"from":"0x0aaa289E4DBeecD5E59856d67C775202932Bb411","to":"0xB9C2....fF","data":"0xa0...2710","accessList":null}, error={"name":"ProviderError","code":3,"_isProviderError":true,"data":"0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001077726f6e67206d696e742076616c756500000000000000000000000000000000"}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.6.6)
Not quite sure why I am getting this error, any help would be greatly appreciated.
Thanks ahead of time.
require(msg.value == _amount * mintPrice, 'wrong mint value');
This condition in the mint() function is not met, which effectively fails to estimate gas needed to run the transaction because the transaction would revert.
Solution: Pass a correct amount of ETH (value param of the transaction) that will pass the condition.
I was having same issue yesterday, what you can do is add a gas limit manually to the transection, in your case when calling the mint function in the hardhat script, you can add manual gasLimit to it, for example.
YourInstanceName.mint(10, { gasLimit: 1 * 10 ** 6 })
btw I found another similar stackoverflow question link you can check it out.

Swap ETH to DAI using ISwapRouter from Uniswap

I am trying to get started with Uniswap V3. As an example, I took the most basic use case: Given X amount of ETH do a swap to DAI. Unfortunately, I am not being able to make it work.
There is already a very similar question (with no answer) but slightly different as the code doesn't look like mine.
I am using Hardhat to fork the main-net and then I connect Remix to localhost:8545
npx hardhat node --fork https://mainnet.infura.io/v3/{MY_API_KEY}
Hardhat config down below:
solidity: {
compilers: [
{
version: "0.8.7",
settings: {
optimizer: {
enabled: true,
runs: 1000,
}
}
}
]
}
As you can notice (full contract at the very bottom), the contract offers 3 payable functions:
function convertExactEthToDai() external payable;
function convertEthToExactDai(uint256 daiAmount) external payable;
function getEstimatedETHforDAI(uint daiAmount) external payable returns (uint256);
All of them fail, even getEstimatedETHforDAI, which is fairly simple and readonly (almost). There is no given reason, so I am blind. When I execute the function from Remix, I just get a generic error "Returned error: Error: Transaction reverted without a reason string".
When I look at hardhat console, I see this error:
eth_sendTransaction
Contract call: <UnrecognizedContract>
Transaction: 0xe17fd5a07ca4a0d5a0f91525a77d21152c41f4dc2a9e59feaac4fec7452ba3a1
From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
To: 0xc351628eb244ec633d5f21fbd6621e1a683b1181
Value: 0 ETH
Gas used: 52351 of 3000000
Block #13238807: 0x7471674d8b76462230d687644e20970137640a7b2fe005c264a04c2af35d4985
Error: Transaction reverted without a reason string
at <UnrecognizedContract>.<unknown> (0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6)
at <UnrecognizedContract>.<unknown> (0xc351628eb244ec633d5f21fbd6621e1a683b1181)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at HardhatNode._mineBlockWithPendingTxs (D:\Repositories\TheRock\facutherock.blockchain.gettingstarted\node_modules\hardhat\src\internal\hardhat-network\provider\node.ts:1582:23)
at HardhatNode.mineBlock (D:\Repositories\TheRock\facutherock.blockchain.gettingstarted\node_modules\hardhat\src\internal\hardhat-network\provider\node.ts:435:16)
at EthModule._sendTransactionAndReturnHash (D:\Repositories\TheRock\facutherock.blockchain.gettingstarted\node_modules\hardhat\src\internal\hardhat-network\provider\modules\eth.ts:1494:18)
at HardhatNetworkProvider._sendWithLogging (D:\Repositories\TheRock\facutherock.blockchain.gettingstarted\node_modules\hardhat\src\internal\hardhat-network\provider\provider.ts:129:22)
at HardhatNetworkProvider.request (D:\Repositories\TheRock\facutherock.blockchain.gettingstarted\node_modules\hardhat\src\internal\hardhat-network\provider\provider.ts:106:18)
Looks like the contract is invalid, however I can in EtherScan the Quoter and the Router
Any idea? I really appreciate it.
Here is the full contract
// SPDX-License-Identifier: UNLICENCED
pragma solidity ^0.8.0;
pragma abicoder v2;
import "https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/interfaces/ISwapRouter.sol";
import "https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/interfaces/IQuoter.sol";
interface IUniswapRouter is ISwapRouter {
function refundETH() external payable;
}
contract Uniswap3 {
IUniswapRouter public constant uniswapRouter = IUniswapRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
IQuoter public constant quoter = IQuoter(0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6);
address private constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
address private constant WETH9 = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;
function convertExactEthToDai() external payable {
require(msg.value > 0, "Must pass non 0 ETH amount");
uint256 deadline = block.timestamp + 15;
address tokenIn = WETH9;
address tokenOut = DAI;
uint24 fee = 3000;
address recipient = msg.sender;
uint256 amountIn = msg.value;
uint256 amountOutMinimum = 1;
uint160 sqrtPriceLimitX96 = 0;
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams(
tokenIn,
tokenOut,
fee,
recipient,
deadline,
amountIn,
amountOutMinimum,
sqrtPriceLimitX96
);
uniswapRouter.exactInputSingle{ value: msg.value }(params);
uniswapRouter.refundETH();
// refund leftover ETH to user
(bool success,) = msg.sender.call{ value: address(this).balance }("");
require(success, "refund failed");
}
function convertEthToExactDai(uint256 daiAmount) external payable {
require(daiAmount > 0, "Must pass non 0 DAI amount");
require(msg.value > 0, "Must pass non 0 ETH amount");
uint256 deadline = block.timestamp + 15; // using 'now' for convenience, for mainnet pass deadline from frontend!
address tokenIn = WETH9;
address tokenOut = DAI;
uint24 fee = 3000;
address recipient = msg.sender;
uint256 amountOut = daiAmount;
uint256 amountInMaximum = msg.value;
uint160 sqrtPriceLimitX96 = 0;
ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams(
tokenIn,
tokenOut,
fee,
recipient,
deadline,
amountOut,
amountInMaximum,
sqrtPriceLimitX96
);
uniswapRouter.exactOutputSingle{ value: msg.value }(params);
uniswapRouter.refundETH();
// refund leftover ETH to user
(bool success,) = msg.sender.call{ value: address(this).balance }("");
require(success, "refund failed");
}
// do not used on-chain, gas inefficient!
function getEstimatedETHforDAI(uint daiAmount) external payable returns (uint256) {
address tokenIn = WETH9;
address tokenOut = DAI;
uint24 fee = 10000;
uint160 sqrtPriceLimitX96 = 0;
return quoter.quoteExactOutputSingle(
tokenIn,
tokenOut,
fee,
daiAmount,
sqrtPriceLimitX96
);
}
// important to receive ETH
receive() payable external {}
}

Token balance shows 0 in rinkeby etherscan

I wrote a erc20 token contract and I deployed in rinkeby tetstnet. I given the toatl supply=1000000 but my token balance is showing 0 in metamask. How can I get the tokens and tell me the way to get the tokens. Below is my contract
pragma solidity ^0.5.0;
contract COCOTOKEN {
string public constant symbol = "COCO";
string public constant name = "COCOTOKEN";
uint8 public constant decimals = 18;
uint256 totalSupply = 1000000;
address public owner;
mapping(address => uint256) balances;
mapping(address => mapping (address => uint256)) allowed;
modifier onlyOwner {
require(msg.sender == owner);
_;
}
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
constructor() public{
owner = msg.sender;
balances[owner] = totalSupply;
}
function balanceOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
function transfer(address _to, uint256 _amount) public returns (bool success) {
if (balances[msg.sender] >= _amount
&& _amount > 0
&& balances[_to] + _amount > balances[_to]) {
balances[msg.sender] -= _amount;
balances[_to] += _amount;
emit Transfer(msg.sender, _to, _amount);
return true;
} else {
return false;
}
}
function transferFrom(
address _from,
address _to,
uint256 _amount
) public returns (bool success) {
if (balances[_from] >= _amount
&& allowed[_from][msg.sender] >= _amount
&& _amount > 0
&& balances[_to] + _amount > balances[_to]) {
balances[_from] -= _amount;
allowed[_from][msg.sender] -= _amount;
balances[_to] += _amount;
emit Transfer(_from, _to, _amount);
return true;
} else {
return false;
}
}
function approve(address _spender, uint256 _amount) public returns (bool success) {
allowed[msg.sender][_spender] = _amount;
emit Approval(msg.sender, _spender, _amount);
return true;
}
function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
return allowed[_owner][_spender];
}
}
and the the deployed contract address is "0xc3384a37d041b99d437734a80e88b39e0efa630d".Why token balance is showing 0.In rinkeby etehrscan it showing liks following
On-chain Token Attributes Check Result:
Total Supply = 0
Name = COCOTOKEN
Symbol = COCO
Decimals = 18
ERC-165 Interface = {Not Available}
Implements ERC-721 = {Not Available}.
Can any one please tell me how to add tokens?
Because that is very small unit of your ether. just transfer for ether from faucet.
or just transfer in wei unit 1000000000000000000 then you will be see 1 ether on your screen.
You need to increase your totalSupply of with 18 digits of the decimal. for more explanation on decimal and totalSupply check this Answer.
The value that you assegned at the totalSupply is too low,you can check the erc20 token standard here. In the constructor they set the totalSupply like in the code below:
constructor() public {
symbol = "FIXED";
name = "Example Fixed Supply Token";
decimals = 18;
_totalSupply = 1000000 * 10**uint(decimals);
balances[owner] = _totalSupply;
emit Transfer(address(0), owner, _totalSupply);
}
The total supply you are giving is like totalsupply = 1000000 * 10^-18 which would come to 0.0000000000001 so obviously it will show as zero when you try to perform any transaction.
Here is a complete implementation using OpenZeppelin which sets total supply to 1000000 and assigns the tokens to you at contract initialization.
pragma solidity 0.5.2;
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
contract TokenMock is ERC20
{
constructor () public {
_mint(msg.sender, 1000000);
}
}