아무것도 하지 않은 상태에서의 

window.web3 obj의 상태. obj는 proxy obj이며 진짜 obj 내용은 target 안 l 안에 있다.

프록시 obj 참고자료 ) https://blog.woolta.com/categories/3/posts/144

image

아무것도 하지 않은 상태에서의

window.ethereum obj의 상태(위의 window.web3와 매우 유사하다)

image

.

.

.

const provider = new Web3.providers.HttpProvider(        "https://polygon-mainnet.g.alchemy.com/v2/xk……..qk"    );    const web3 = new Web3(provider);

를 하고 난후에도 window.web3, window.ethereum의 내용은 위와같았다.

.

.

참고)

web3는 deprecated될 부분이고 ethereum을 이용해야한다.

공식문서 해결방법 https://docs.metamask.io/guide/provider-migration.html#replacing-window-web3

https://youtu.be/IZNcHkrEfbA

https://github.com/dappuniversity/token_sniping_bot/blob/master/bot.js

image
image
image
// Intianiate Web3 connection
const Web3 = require('web3')
const web3 = new Web3('ws://127.0.0.1:7545') // Replace this with a websocket connection to your alchemy node to monitor mainnet

const IUniswapV2Factory = require("@uniswap/v2-core/build/IUniswapV2Factory.json")
const IUniswapV2Router02 = require('@uniswap/v2-periphery/build/IUniswapV2Router02.json')
const IUniswapV2Pair = require('@uniswap/v2-core/build/IUniswapV2Pair.json')
const IERC20 = require('@openzeppelin/contracts/build/contracts/ERC20.json')

const uFactoryAddress = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f'
const uRouterAddress = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D'

const uFactory = new web3.eth.Contract(IUniswapV2Factory.abi, uFactoryAddress)
const uRouter = new web3.eth.Contract(IUniswapV2Router02.abi, uRouterAddress)
const WETH = new web3.eth.Contract(IERC20.abi, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2')

const AMOUNT = '0.25' // How much WETH are you willing to spend on new tokens?
const SLIPPAGE = 0.05 // 5% Slippage

const main = async () => {

    const [deployer, sniper] = await web3.eth.getAccounts()

    // Create event listener to listen to PairCreated
    uFactory.events.PairCreated({}, async (error, event) => {
        console.log(`New pair detected...n`)

        const { token0, token1, pair } = event.returnValues
        console.log(`Token0: ${token0}`)
        console.log(`Token1: ${token1}`)
        console.log(`Pair Address: ${pair}n`)

        // Since we are buying this new token with WETH, we want to verify token0 & token1 address, and fetch the address of the new token?
        let path = []

        if (token0 === WETH._address) {
            path = [token0, token1]
        }

        if (token1 === WETH._address) {
            path = [token1, token0]
        }

        if (path.length === 0) {
            console.log(`Pair wasn't created with WETH...n`)
            return
        }

        const uPair = new web3.eth.Contract(IUniswapV2Pair.abi, pair)
        const token = new web3.eth.Contract(IERC20.abi, path[1]) // Path[1] will always be the token we are buying.

        console.log(`Checking liquidity...n`)

        // Ideally you'll probably want to take a closer look at reserves, and price from the pair address
        // to determine if you want to snipe this particular token...
        const reserves = await uPair.methods.getReserves().call()

        if (reserves[0] == 0 && reserves[1] == 0) {
            console.log(`Token has no liquidity...`)
            return
        }

        console.log(`Swapping WETH...n`)

        try {
            const amountIn = new web3.utils.BN(web3.utils.toWei(AMOUNT, 'ether'))
            const amounts = await uRouter.methods.getAmountsOut(amountIn, path).call()
            const amountOut = String(amounts[1] - (amounts[1] * SLIPPAGE))
            const deadline = Date.now() + 1000 * 60 * 10

            await WETH.methods.approve(uRouter._address, amountIn).send({ from: sniper })

            const gas = await uRouter.methods.swapExactTokensForTokens(amountIn, amountOut, path, sniper, deadline).estimateGas({ from: sniper })
            await uRouter.methods.swapExactTokensForTokens(amountIn, amountOut, path, sniper, deadline).send({ from: sniper, gas: gas })

            console.log(`Swap Successfuln`)

            // Check user balance of token:
            const symbol = await token.methods.symbol().call()
            const tokenBalance = await token.methods.balanceOf(sniper).call()

            console.log(`Successfully swapped ${AMOUNT} WETH for ${web3.utils.fromWei(tokenBalance.toString(), 'ether')} ${symbol}n`)
        } catch (error) {
            console.log(`Error Occured while swapping...`)
            console.log(`You may need to adjust slippage, or amountIn.n`)
            console.log(error)
        }

        console.log(`Listening for new pairs...n`)

    })

    console.log(`Listening for new pairs...n`)
}

main()

https://ethereum.stackexchange.com/a/11295

1.The number of decimals in the tokens is different: 6 decimals for USDC, 18 decimals for WETH, leading to one “unit” of USDC being worth much more than one unit (wei) of WETH.

2.The contract address of the USDC token is lower than the contract address of WETH9 on the ETH mainnet. Uniswap pairs are always in the same order, based on token addresses. This means that the price is expressed for USDC in terms of WETH.

To get the real price of ETH in terms of USDC, adjust for the decimals, and then invert the result (the inverted value of x is 1/x). The result is 4479.50.

In Python code:

price = 223239120
adjusted_price = price / (10 ** (18 - 6))
inverted_price = 1 / adjusted_price
print(inverted_price)

1usdc 가 몇 eth 인지 알고 싶은 경우 

weth reserve / (10^18) / usdc reserve / (10^6)

1eth가 몇 usdc인지 알고 싶은 경우 위의 가격을 invert하면 된다.

const UNISWAP_FACTORY_ADDR = "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f";
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
const WETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";

async function main(){
  var factory = new web3.eth.Contract(factoryABI.abi, UNISWAP_FACTORY_ADDR);
  var pairAddress = await factory.methods.getPair(WETH, USDC).call();
  var pair = new web3.eth.Contract(pairABI.abi, pairAddress);
  var reserves = await pair.methods.getReserves().call();
  console.log(pairAddress);
  console.log(reserves);
  console.log(reserves[1] / reserves[0]);
}

uniswap 기반 dex의 경우 pair 에 getReserves()를 하게 되면 기본적으로 usde , weth의 순으로 reserve가 나오게 된다.