I need to understand below smart contract code - solidity

Can you help me explain below smart contract code I found on tomb finance, tomb.sol contract?
// Initial distribution for the first 24h genesis pools
uint256 public constant INITIAL_GENESIS_POOL_DISTRIBUTION = 11000 ether;
// Initial distribution for the day 2-5 TOMB-WFTM LP -> TOMB pool
uint256 public constant INITIAL_TOMB_POOL_DISTRIBUTION = 140000 ether;
// Distribution for airdrops wallet
uint256 public constant INITIAL_AIRDROP_WALLET_DISTRIBUTION = 9000 ether;
Why do they distribute ether for the pools?
Why ether?
Can they do that?
What exactly is the value of 1 ether?
If they had deployed this on BNB Chain, will this code will change?

This snippet alone doesn't distribute any ether, it only declares 3 constants. It's likely that there's some other functions in the code, that wasn't shared, that make use of these constants.
ether in this case is a Solidity global unit. No matter on which network you deploy the contract, it multiplies the specified number by 10^18 (or 1000000000000000000). Current version of Solidity (0.8) is not able to store decimal numbers, so all native and ERC-20 balances are stored in the smallest units of the token. In case of native tokens (ETH on Ethereum, MATIC on Polygon, ...), that's wei. And 10^18 wei == 1 ETH (or 1 MATIC, etc - depending on the network).
If this code was deployed on other EVM network (such as Binance Smart Chain), the ether unit is the same. It doesn't work with ETH tokens, it "just" multiplies the number.

Related

Difference of balance keyword between different blockchain

I know that the address(this).balance shows the eth balance of the target contract.
Does the balance keyword return the balance of the native currency of that blockchain, or always returns balance of the contract's eth's?
If my SC is deployed on the polygon, does the balance keyword return the matic balance of my contract?
It always returns native balance of the address on the specific network where the contract is deployed.
ETH on Ethereum
MATIC on Polygon
BNB on Binance Smart Chain
etc.

Solidity -- using uninitialized storage pointers safely

I'm trying to gas-optimize the following solidity function by allowing users to sort the array they pass in such a way that I can perform less storage reads. However, to do this I need to use an uninitialized storage pointer -- which the compiler doesnt let me do (^0.8.0). How can I safely use an uninitialized storage pointer and have it be accepted by the compiler?
function safeBatchReleaseCollaterals(
uint256[] memory bondIds,
uint256[] memory collateralIds,
address to
) public {
// 'memoization' variables
uint256 lastAuthorizedBond = 2**256 - 1;
uint256 lastCurrencyRef = 2**256 - 1;
Currency storage currency;
for (uint256 i = 0; i < bondIds.length; i++) {
uint256 bondId = bondIds[i];
// check if we authorized this bond previously?
if (lastAuthorizedBond != bondId) {
require( // expensive check. Reads 2 slots!!
_isAuthorizedToReleaseCollateral(bondId, msg.sender),
"CollateralManager: unauthorized to release collateral"
);
lastAuthorizedBond = bondId;
}
uint256 collateralId = collateralIds[i];
Collateral storage c = collateral[bondId][collateralId];
// check if we read this Currency previously?
if (lastCurrencyRef != c.currencyRef) {
currency = currencies[c.currencyRef]; // expensive 1 slot read
lastCurrencyRef = c.currencyRef;
}
_transferGenericCurrency(currency, address(this), to, c.amountOrId, "");
emit CollateralReleased(bondId, collateralId, to);
}
}
As a quick explanation of the structure: this is similar to a batch erc1155 transfer, except I'm storing a lot of data related to the transaction in some slots under the Currency and Collateral and Bond objects. Since the reads can get intensive, I want to optimize gas by caching reads. Since having an actual cache map is also expensive, I instead optimize by caching only the previous list item, and rely on the user to sort the array in such a way that results in the smallest gas costs.
The lastAuthorizedBond variable caches which bondId was last authorized -- if it repeats, we can cut out an expensive 2-slot read! (which results in maybe 16% gas savings during tests. You can see, significant). I tried doing something similar with the currency read, storing the lastCurrencyRef and hoping to store the actual result of the read into the currency variable. The compiler complains about this however, and maybe justly so.
Is there a way to pass this by the compiler? Do I just have to ditch this optimization? Though nobody is allowed to register the 2**256-1 currency or bond, is this code even safe?
Note that the collateral entry gets deleted after this runs -- cannot double release.

exchange own ERC20 token to another token in smart contract for Game

I want to deploy a smart contract (ERC20) for the game,
so the purpose is to keep points.
when someone enters the game, we will ask for some crypto coin (ex. ETH) and give some of our own points
while playing the game, the user will earn some points.
Then that user can get crypto coins (ex. ETH) from that points.
I can write a smart contract to manage points.
But I wonder if I can have a function to exchange our points to existing crypto coins (ex ETH) inside of our smart contract.
Does someone know the right way to do it?
You can calculate the amount of ETH based on a price, and then use the transfer() native function of address payable type.
mapping (address => uint256) pointBalances;
// 1 point for 100 wei, assuming the points have 0 decimals
uint256 price = 100;
function sellPoints(uint256 _amount) external {
require(pointBalances[msg.sender] >= _amount, "Insufficient balance");
pointBalances[msg.sender] -= _amount;
uint256 weiAmount = _amount * price;
payable(msg.sender).transfer(weiAmount);
}

Uniswapv2 addLiquidity Decimal error in Remix (Bignumber)

I'm testing Uniswapv2 for a project and am getting this error:
transact to UniswapV2Router02.addLiquidity errored: Error encoding arguments: Error: invalid BigNumber string (argument="value", value=".004", code=INVALID_ARGUMENT, version=bignumber/5.1.1)
The Uniswapv2 code is normal and unedited. I tested these number on Uniswap itself to make sure the numbers worked before I tried them in Remix. These are what I tried to pass:
tokenA: 0xc778417e063141139fce010982780140aa0cd5ab (WETH since I can't find ETH address)
tokenB: 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984 (UNI)
amountADesired: 0.004
amountBDesired: 0.03
amountAMin:1
amountBMin:2
to: 0xd50eCE9501a1f63e449DbBBbBdc5CB59f3e2c231
deadline: 255
Solidity contracts don't take decimal arguments. Instead, you need to pass the amount of smallest units.
WETH (note - you have an incorrect address in your question) has 18 decimals, UNI has 18 as well.
1 WETH is 1000000000000000000 (or 10^18) units.
So if you want to pass 0.004 WETH in the argument, you need to input the number 4000000000000000 (which is 0.004 * 10^18).
Note: ETH is the native currency of the Ethereum network, so there is no token address for ETH. Uniswap v2 Router 2 has a function addLiquidityETH() for when you want to add liquidity to a pair of a token to ETH.

Multiplication and Division with contract value

I am trying to insert a if-clause in the following contract to check if the withdrawal (it is a sample bank contract) is less than the 10% of the whole contracts value, i.e. of the complete bank.
When I insert the code as below it gives me an error such as
"UnimplementedFeatureError: Not yet implemented - FixedPointType."
What am I doing wrong?
Can you help me?
Many thanks in advance!!
pragma solidity ^0.4.24;
contract bank{
mapping (address => uint) private balance;
address public Owner;
function WithDrawMoreMoney(uint a) public{
require (balance[msg.sender]>=0);
require (address(this).balance>=0);
require ((a) =< (address (this).balance)*(uint(1.1))); // The problematic line
balance[msg.sender]-=a;
(msg.sender).transfer(a);
check if the withdrawal ... is less than [10%] of the whole [contract's] value
I think you just want this:
require(a <= address(this).balance / 10);
Your code multiplied by 1.1 when I think you meant 0.1, but either way Solidity only has integers. Dividing by 10 works. You also had a typo: =< instead of <=.
If you want to check some other percentage, like 23%:
require(a <= address(this).balance * 23 / 100);
Make sure to do the multiplication first, and always remember to guard against integer overflows.