how to format a uint that's holding a price in ETH on solidity - solidity

Quick question let say I have product number 1 which its price is declared as 8 eth, is there a way to format it to avoid insering it in Wei on solidity?

A literal number can take a suffix of wei, gwei or ether to specify a subdenomination of Ether, where Ether numbers without a postfix are assumed to be Wei.
contract EtherUnits {
uint public oneWei = 1 wei;
// 1 wei is equal to 1
bool public isOneWei = 1 wei == 1;
uint public oneEther = 1 ether;
// 1 ether is equal to 10^18 wei
bool public isOneEther = 1 ether == 1e18;
}

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]]);
}
}
}

Why much more gas are used when calling a function for the first time?

Here is my code.
contract Demo {
function add1(uint256 a, uint256 b) public pure returns (uint256) {
if (a==0) {
return 0;
}
uint256 c = a + b;
return c;
}
}
contract Test {
Demo demo = new Demo();
function testGas() public {
uint256 startGas = gasleft();
demo.add1(1, 2);
uint256 endGas = gasleft();
uint256 gasUsage1 = startGas - endGas;
startGas = gasleft();
demo.add1(1, 2);
endGas = gasleft();
uint256 gasUsage2 = startGas - endGas;
}
}
The gasUsage1 is 6434 and gasUsage2 is 1919.
When the function is called a third time, the gas usage is the same as the second time.
I tested other functions and the results were the same.
There are two main contributions: reading the address from storage, and then touching it.
By doing demo.add1(1, 2); the code first needs to read (SLOAD) the address of demo saved in storage. The gas cost is 2100 the first time (cold access), then 100 (warm access). docs
Calling the demo contract will "touch" its address. The gas cost the first time (cold access) is 2600, then its 100. docs
This explain a 2000+2500 = 4500 difference.
So, 6434-(1919+4500) = 15. There's only 15 extra gas, that's probably due to stack/memory operations.

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

uint256 input in RemixIDE

I'm trying to learn developing my first smart contract in order to use flash loans on aave. I have a problem regarding the amount input for the transaction.
I've a function asking for the amount of token I need and the type is uint256. When I type 10 I only receive 0.0000000000000001 by the flash loan. Why? Maybe it's a stupid question but I'm not understanding what's wrong.
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
import { FlashLoanReceiverBase } from "./FlashLoanReceiverBase.sol";
import { ILendingPool, ILendingPoolAddressesProvider, IERC20 } from "./Interfaces.sol";
import { SafeMath } from "./Libraries.sol";
import "./Ownable.sol";
/*
* A contract that executes the following logic in a single atomic transaction:
*
*
*/
contract BatchFlashDemo is FlashLoanReceiverBase, Ownable {
ILendingPoolAddressesProvider provider;
using SafeMath for uint256;
uint256 flashDaiAmt0;
address lendingPoolAddr;
// mumbai reserve asset addresses
address mumbaiDai = 0x001B3B4d0F3714Ca98ba10F6042DaEbF0B1B7b6F;
// intantiate lending pool addresses provider and get lending pool address
constructor(ILendingPoolAddressesProvider _addressProvider) FlashLoanReceiverBase(_addressProvider) public {
provider = _addressProvider;
lendingPoolAddr = provider.getLendingPool();
}
/**
This function is called after your contract has received the flash loaned amount
*/
function executeOperation(
address[] calldata assets,
uint256[] calldata amounts,
uint256[] calldata premiums,
address initiator,
bytes calldata params
)
external
override
returns (bool)
{
/*
*
*
*/
// Approve the LendingPool contract allowance to *pull* the owed amount
// i.e. AAVE V2's way of repaying the flash loan
for (uint i = 0; i < assets.length; i++) {
uint amountOwing = amounts[i].add(premiums[i]);
IERC20(assets[i]).approve(address(_lendingPool), amountOwing);
}
return true;
}
/*
* This function is manually called to commence the flash loans sequence
*/
function executeFlashLoans(uint256 _flashDaiAmt0) public onlyOwner {
address receiverAddress = address(this);
// the various assets to be flashed
address[] memory assets = new address[](1);
assets[0] = mumbaiDai;
// the amount to be flashed for each asset
uint256[] memory amounts = new uint256[](1);
amounts[0] = _flashDaiAmt0;
flashDaiAmt0 = _flashDaiAmt0;
// 0 = no debt, 1 = stable, 2 = variable
uint256[] memory modes = new uint256[](1);
modes[0] = 0;
address onBehalfOf = address(this);
bytes memory params = "";
uint16 referralCode = 0;
_lendingPool.flashLoan(
receiverAddress,
assets,
amounts,
modes,
onBehalfOf,
params,
referralCode
);
}
/*
* Rugpull all ERC20 tokens from the contract
*/
function rugPull() public payable onlyOwner {
// withdraw all ETH
msg.sender.call{ value: address(this).balance }("");
// withdraw all x ERC20 tokens
IERC20(mumbaiDai).transfer(msg.sender, IERC20(mumbaiDai).balanceOf(address(this)));
}
}
I'm deploying passing this address as parameter:
0x178113104fEcbcD7fF8669a0150721e231F0FD4B
it is the Lending Pool Addresses Provider contract taken from here: https://docs.aave.com/developers/v/2.0/deployed-contracts/matic-polygon-market.
When I try asking for more than 1000tokens I get the error. Hope this helps to reproduce.
EVM doesn't support decimal numbers. So a common approach is to declare a number of decimals in the contract, and then include them with the stored values.
Example:
When a contract uses 2 decimals, value of 1 is stored as 100.
Aave protocol works with ERC20 tokens, where the standard defines a function named decimals() to return a number of decimal places.

Solidity decimal values

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)