How can I get pool with ETH in Uniswap v3? - ethereum

I want to get pool with ETH (ETH/UNI, ETH/USDC, ...).
I tried to call getPool() function of uniswap factory contract with 0x0000000000000000000000000000000000000000, but it returns 0x0, which means there is no pool.

There are no pools with ETH in Uniswap v3 (or v2 for that matter), only pools with ERC-20 wrapped ETH (WETH). The address of the WETH token depends on the network, for instance, for the Ethereum mainnet it is 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2. Use this address as an argument for the getPool function.
For instance, to get the UNI/WETH 0.3% pool (UNI token address is 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984 on the mainnet), call:
getPool('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
3000)
Something to note: the pool addresses are deterministic and can also b computed off-chain. See here for example code.

Related

Can I make [subsidy halving] in solidity?

I want to make new coin in solidity.
I found the code how to make subsidy halving in Bitcoin clone coding.
Can I make subsidy halving in solidity?(ERC-20, 721, 1155 whatever)
I can't find any subsidy halving in ERC coin.
Sorry for my poor English.
I want to assume that you mean: "Bitcoin Halving." Given that is the case, in Solidity, what is available is: "Token burning".
To ensure that you understand: Bitcoin Halving is an event that occurs where the block reward given to Bitcoin miners for processing transactions is cut in half.
Token Burning in Ethereum is a way of removing tokens from circulation by sending the tokens to a "dead address" this renders the token "unspendable." This is often done to reduce the amount of the said token in circulation. This ultimately affects the token liquidity.
The simple function below illustrates Polygon MATIC token burning:
function _burn(address account, uint256 value) internal {
require(account != address(0));
_totalSupply = _totalSupply.sub(value);
_balances[account] = _balances[account].sub(value);
emit Transfer(account, address(0), value);
}
The above function is part of the functions deployed when initializing a token contract in solidity. With this function as part of the deployed contract code, you can burn any token type: ERC20, ERC721 ...
You will find this resource useful to understand more: https://academy.binance.com/en/articles/what-is-a-coin-burn

Identical contract on BNB chain fails, working on ETH

I have two contracts of identical ERC20 code, but on BNB chain the functions fail, such as allowance, and on Ethereum they are fine.
I can't seem to understand why, I've never seen this happen before. I tested on Fantom testnet as well, and it also fails.
https://ropsten.etherscan.io/address/0xe95fc92e1ae8b46e83fc970f9a5f28c9439839ff#readContract
https://testnet.bscscan.com/address/0x6f74C965Fe9A27d3A84c88c83F4700351b0c2e8d#readContract
Allowance returns uint256 : Error: Wrong response id "0" (expected: "8") in {"jsonrpc":"2.0" on BNB chain
And passes on ETH
The allowance is different for every chain.
You need to call the approve function on each chain where you want to give allowance.

TransferFrom failed in Router pancakeswap v2

I'm trying to use the "swapExactTokensForTokens" function from the pancakeswap Router contract on the testnet.
The pair that I am trying to use is the WBNB / ETH.
I already approved the amount in the WBNB contract. I also use the function "getAmountsOut"
But I always get the same error:
Fail with error 'TransferHelper :: transferFrom: transferFrom failed'
Router Address: https://testnet.bscscan.com/address/0x9Ac64Cc6e4415144C455BD8E4837Fea55603e5c3#readContract
WBNB Address: https://testnet.bscscan.com/address/0xae13d989dac2f0debff460ac112a837c89baa7cd
ETH Address: https://testnet.bscscan.com/address/0x8babbb98678facc7342735486c851abd7a0d17ca
Transaction detail: https://testnet.bscscan.com/tx/0x23b9c4d80e443766d0fe2c33b7f398b0b639f735af06f7488bd6e56d68414014
Any help is welcome, thank you very much

solidity: call contract function from another contract with the same msg.sender

I have a function that needs to call the transfer method on another contract.
I want the transfer method to be called from the address of the original caller and not the contract.
Is it possible?
This is the code:
function buyGameBundle(string calldata id) external nonReentrant {
structGameBundles memory currentItem = _gameBundles[id];
require(currentItem.exists == true, "bundle does not exists");
require(currentItem.totalSupply > 0, "there are no more bundles left");
if (currentItem.cost > 0) {
erc20.transfer(_feesAccount, currentItem.cost);
}
currentItem.totalSupply = currentItem.totalSupply.sub(1);
_gameBundles[id] = currentItem;
emit BuyGameBundle(_msgSender(), id, currentItem.cost);
}
erc20.transfer(_feesAccount, currentItem.cost);
Your current code performs a message call (docs). Another name for the same thing is an EVM call. It uses storage of the target contract, and the msg.sender is your contract (not the original transaction sender).
If you want the msg.sender to be the original transaction sender (the user), you need to use a delegatecall (docs). But... a delegatecall uses storage of the caller (your contract; not the called contract), so it's mostly useful for proxy contracts.
For security reasons, it's not possible to execute a function in a target contract, using the target contract storage and msg.sender of the original sender.
If it were possible, you could theoretically steal tokens from anyone who doesn't/can't verify your contract source code. Example:
usdt.transfer(attacker, usdt.balanceOf(victim));
weth.transfer(attacker, weth.balanceOf(victim));
// ...
Needing to transfer funds from someone is such a common pattern that it is built right into the ERC20 specification, and is used in almost every DeFi contract ever.
What you need to use is transferFrom() rather than transfer(). It takes a "from" address as the first parameter, and if the sending user has approved your contract to move their funds, then the call will succeed.
In your case the transfer line would change to:
erc20.transferFrom(msg.sender, _feesAccount, currentItem.cost);
The sender will need to approve your contract first.
Here are the ERC20 specifications.
https://eips.ethereum.org/EIPS/eip-20
If you are using ERC20s and want to transfer another account's tokens from within a seperate contract, the correct method to use is transferFrom. This requires an allowance to be given to the contract in which transferFrom is being called. This is done using approve or increaseAllowance (the latter is recommended).
In general, however, if you wish to call another contract's method in the context of the current contract, i.e. with the same msg.sender (amongst other things), you can use delegatecall. See https://docs.soliditylang.org/en/v0.8.11/types.html#address for more details.

How to find out if an Ethereum address is a contract?

An address in Solidity can be an account or a contract (or other things, such as a transaction). When I have a variable x, holding an address, how can I test if it is a contract or not?
(Yes, I've read the chapter on types in the doc)
Yes you can, by using some EVM assembly code to get the address' code size:
function isContract(address addr) returns (bool) {
uint size;
assembly { size := extcodesize(addr) }
return size > 0;
}
The top-voted answer with the isContract function that uses EXTCODESIZE was discovered to be hackable.
The function will return false if it is invoked from a contract's constructor (because the contract has not been deployed yet).
The code should be used very carefully, if at all, to avoid security hacks such as:
https://www.reddit.com/r/ethereum/comments/916xni/how_to_pwn_fomo3d_a_beginners_guide (archive)
To repeat:
Do not use the EXTCODESIZE check to prevent smart contracts from calling a function. This is not foolproof, it can be subverted by a constructor call, due to the fact that while the constructor is running, EXTCODESIZE for that address returns 0.
See sample code for a contract that tricks EXTCODESIZE to return 0.
Checking if a caller is a contract
If you want to make sure that an EOA is calling your contract, a simple way is require(msg.sender == tx.origin). However, preventing a contract is an anti-pattern with security and interoperability considerations.
require(msg.sender == tx.origin) will need revisiting when account abstraction is implemented.
Checking if a callee is a contract
As #Luke points out in a comment, there is no general on-chain way to find out about a callee. If you want to "call" an address, there's no general way to find out if that address is a contract, EOA, or an address that a new contract can be deployed on, or if it's a CREATE2 address.
One non-general way that works for some callees: you can have a mapping on-chain that stores addresses of known EOAs or contracts. (Just remember that for an address without any on-chain history, you can't know if it's an EOA or an address that a contract can be deployed on.)
This isn't something you can query from within a contract using Solidity, but if you were just wanting to know whether an address holds contract code or not, you can check using your geth console or similar with eg:
> eth.getCode("0xbfb2e296d9cf3e593e79981235aed29ab9984c0f")
with the hex string (here 0xbfb2e296d9cf3e593e79981235aed29ab9984c0f) as the address you wish to query. This will return the bytecode stored at that address.
You can also use a blockchain scanner to find the source code of the contract at that address, for example the ecsol library as shown on etherscan.io.
Edit: Solidity has changed since this answer was first written, #manuel-aráoz has the correct answer.
There is no way in solidity to check if an address is a contract. One of the goals of Ethereum is for humans and smart contracts to both be treated equally. This leads into a future where smart contracts interact seamlessly with humans and other contracts. It might change in the future , but for now an arbitrary address is ambiguous.
If you want to use nodejs to confirm, you can do this:
const Web3 = require('web3')
// make sure you are running geth locally
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
is_contract = async function(address) {
res = await web3.eth.getCode(address)
return res.length > 5
}
is_contract('your address').then(console.log)
From openzeppeling Address.sol library, it has this function:
pragma solidity ^0.8.1;
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
isContract will return false for the following types of addresses:
an externally-owned account
a contract in construction
an address where a contract will be created
an address where a contract lived, but was destroyed
What you can do, granted you have the information at hand.
If the transactions sender address was null or unoccupied then you can tell if the address is a contract account or an EOA (externally owned account).
i.e. when sending a create contract transaction on the network then the receive address in the transaction is null/not used.
Reference from github:
https://github.com/ethereum/go-ethereum/wiki/Contracts-and-Transactions
Hope this helps.
If you are checking whether the caller is an EOA rather than a contract:
Short answer:
require(tx.origin == msg.sender);
tx.origin is a reference of the original address who initiates this serial function call, while msg.sender is the address who directly calls the target function. Which means, tx.origin must be a human, msg.sender can be a contract or human. Thus, if someone calls you from a contract, then the msg.sender is a contract address which is different from tx.origin.
I know most contracts may use #Manuel Aráoz's code, which works in most cases. But if you call a function within the constructor of a contract, extcodesize will return 0 which fails the isContract check.
NOTE: DON'T use tx.origin under other circumstances if you are not clear about what it represents because .