web3js Uniswap handle event log data - ethereum

I am building a scraper to get all Swap data from Uniswap using web3js.
So far I subscribe to the log and filter topics by Swap() event.
then I decode the data and get amount0In, amount1In, amount0Out, amount1Out.
My problem is in the swapExactETHForTokensSupportingFeeOnTransferTokens() function.
Normally a swap has token0 in and token1 out, but this function gives me values for 3 of the 4 and I can not seem to understand how to handle that. eventually what I want is to know what they spend, what they got and what I need to update the new reserves of that pair.
If someone has the understanding of the Uniswap RouterV2 contract swap functions, I would like to get some pointers on how to handle the data to get my calculations right.

I found the solution here ethereum.stackexchange Anyone with the same question gets a very detailed answer there.
some contracts actually transfers to recipient specified amount of tokens minus 10% (5% tax fee and 5% liquidity fee) 208940457743532637 - 10% = 188046411969179375 and emits Transfer event. Then, PancakePair _swap function emits Swap event with base value of Amount0Out 208940457743532637
Amount0In is greater than zero because the token contract returns part of tokens as a liquidity pair on Pancake Swap.

Related

UniswapV2Pair, mint function, how is liquidity is created proportion to pair liquidity added

function mint(address to) external lock returns (uint liquidity) {
}
The function above is implemented such that liquidity is added to the to address, however the liquidity is just minted depending on the difference of reserves and balance of token how will it create the liquidity in proportion to liquidity added by sender,
Am i missing something, what if a user always calls the mint function will he not get free LP token added to the address as we can see that the mint function is external not internal
Am i missing something, what if a user always calls the mint function will he not get free LP token added to the address as we can see that the mint function is external not internal
You are missing the function body and all the logic and checks inside it.
what if a user always calls the mint function will he not get free LP token added to the address
The mint() function itself only mints LP tokens to make up for a difference between actual LP balance and expected LP balance. If there's no difference between the actual and expected balances, no LP tokens are minted.
A common practice is to use the router function addLiquidity() which sends tokens to the Pair contract, and then invokes the mint() function - both as part of one transaction, so there's no way to frontrun this action.
If there were underlying tokens sent to the Pair contract without invoking the mint() function, then anyone could invoke this function freely claiming LP tokens representing this difference. However only once, as the LP mint zeros up the difference.
what if a user always calls the mint function will he not get free LP
token added to the address as we can see that the mint function is
external not internal
mint() is called when a user added liquidity.
however the liquidity is just minted depending on the difference of
reserves and balance of token how will it create the liquidity in
proportion to liquidity added by sender,
Because the main equation is based on increasing liquidity is proportional to an increase in LP token shares. This makes sense because adding liquidity has no effect on price, so if you add more liquidity, you should receive LP tokens proportional to what you have received before
Let's say you have T shares and you want to increase liquidity from L0 to L1. How many more shares will be minted for you?
L1 / L0 = (T + mintAmount)/T
We need to find mintAmount.
(L1/L0) * T = T + mintAmount // leave mintAmount alone
((L1/L0)*T) - T = mintAmount // multiply T with L0/L0
((L1/L0)*T) - (T*L0)/L0 = mintAmount
Finally
mintAmount = ((L1-L0)/L0) * T

Block OpenSea trading

Is there a way to avoid trading NFTs on standard marketplaces like OpenSea without breaking the erc721 standard?
If so, how would you go about it?
It is about an NFT that is something like a voucher that can be used 5 times. Over 5 years, once per year. I would like to prevent that someone unknowingly buys a redeemed voucher (for the current year).
You can include checks in your transfer function.
Keep a global map counter with token IDs pointing to the number of transactions per token
mapping(uint256=> uint256) private _tokenTx;
Now, in your transfer function you can use the NFT id, check in the map to see if it's lower than 5, if it is, you fail the tx, otherwise you continue and increase the number
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
**require(_tokenTx[tokenId] <6, "ERC721: can\'t transfer more than 5 times");**
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
**_tokenTx[tokenId] = _tokenTx[tokenId]+1;**
emit Transfer(from, to, tokenId);
}
As for filtering exchanges transfers, you can either keep a dynamic list with the addresses they use, or block the approval processes altogether.
The first keeps the standard better but is harder and more expensive to keep up, the second one is a bit more aggressive but will work for all popular exchanges out there
Or, if you're using an external link to redirect buyers/traders to the text file that lists the voucher code, all you have to do is replace the voucher code(s) with a message saying that all the vouchers have been redeemed and then save the file. That way, the next time the NFT gets traded and they unlock the link, they'll see the message.
I sure as hell ain't going to waste my time trying to figure out all that coding nonesense...lol.

Solidity gas estimation - always out of gas when setting to 0

I'm trying to figure out a solution to this problem, to do with transaction confirmation order and setting values to 0
pragma solidity ^0.5.17;
contract Test {
uint256 amount;
constructor() public {}
function join() public {
amount += 100;
}
function leave() public {
amount -= 100;
}
}
Given these transactions (tested on ropsten):
tx 1) Call Join Confirmed
amount == 100
tx 2) Call Join (gas price 1) Pending
amount == 100 should tx3 get mined first
tx 3) Call Leave (gas price 100) Pending
amount == 0
However tx 2 will always fail with an out of gas error for as long as the amount is set back to 0. This doesn't happen if the value is any higher than 0. My understanding is that it costs more gas to set a value to its 0 state instead of a positive integer, and the gas estimation isn't taking this into account. I've tried delete hoping this would give a gas refund to compensate for the too-low gas limit, but it still failed.
Is there an elegant way to handle this scenario? The only ways I can think of are over-estimating the gas for all join transactions, which has its obvious drawbacks, or never setting amount back to 0.
You are making correct observations.
by setting it to 0 you delete storage, and get gas refund. This is why it takes less amount of gas. But gas refunds have top limit, so you can't use it to store ETH.
It costs 20,000 gas to store one value in a slot (source:https://github.com/ethereum/go-ethereum/blob/d13c59fef0926af0ef0cff0a2e793f95d46442f0/params/protocol_params.go#L41 )
it costs 2,200 gas to load one value from a storage slot (source: https://github.com/ethereum/go-ethereum/blob/d13c59fef0926af0ef0cff0a2e793f95d46442f0/params/protocol_params.go#L89)
That's why you are seeing different gas consumption values.
Just set your gasLimit to some empirically found roughly-estimated value.
Do a trace of your transaction and you will see all gas consumption values.
Now, the way gas refunds work is that during the state transition function, you're asked for the full gas for the run of your contract. During this run, all gas refunds are accumulated in StateDB (temporary state object). At the end of the state transition function, you will get refunds for all storage releases your contract is going to make. This is why you have to set higher gas limit that Etherscan shows, because lets say your contract needs 15,000 gas to run, after storage is released (say for 5,000 gas) , Etherscan will show like the transaction needed 10,000 gas. This is not true because you have got gas refunds at the end, but at the beginning you needed the whole amount of gas (15,000). Gas refunds are sponsored by the miner, his account is going to get less ETH because he is paying you these refunds.

Transfer money between accounts in solidity

I am writing a contract where I want to transfer money (present in the contract owners account and not the contract) to an account address passed to a function in the contract.
for some reason this code won't work
function payBill(uint value, address account) payable public {
account.transfer(value);
transactionCount += 1;
transactionAmount += value;
}
Your problem can be related to any frontend code, not only this.
You've got two options.
get that other user address from the contract and then run a direct transaction between two accounts (example here https://web3js.readthedocs.io/en/v1.2.6/web3-eth.html#id80)
send a value (see here https://web3js.readthedocs.io/en/v1.2.6/web3-eth-contract.html#id33) when you are calling the payBill method. If you don't do it, the default value is zero, and you don't see any transfer.
Also, please consider having a look at this https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/
EDIT:
what you are trying to do here, is also not doable. This requires the contract to have the number of funds that you want to transfer. That is because, with the payable method, you are sending funds to the contract, but the funds will only be in the contract, once the transaction is accepted. On the other hand, you are trying to send that number of funds to another user, without having them on the contract. That is why you never see any balance.

Why Gas Used By Txn is different when invoking the same function in the same smart contract?

I have seen some transactions in etherscan.io.But I have found that even invoking the same function in the same smart contract, the gas used by txn are different.I try to found that maybe the input data result in it.Really?
The input data might be different, but also the state stored in the smart contract might be different (and change e.g. the number of times a loop iterates). Also, if storing nonzero data in a state variable that previously held zero data, or vice versa, will change the gas usage. For example, a simple function that toggles a boolean variable will not use the same amount of gas on any two consecutive calls.
Check out https://ethereum.stackexchange.com/ for future questions like this!
Each time you invoke a function in contract that requires state change in the block,it would cost x amount of gas , so every time you call different or same function in a contract that requires a state change,you would see that x amount of gas is being deducted along with its taxation Id.This is the reason you see different Txn on same function.
More about Gas and Transaction in the link below. http://solidity.readthedocs.io/en/develop/introduction-to-smart-contracts.html