ethers-io / ethers.js

Complete Ethereum library and wallet implementation in JavaScript.
https://ethers.org/
MIT License
7.96k stars 1.85k forks source link

Contract "Mint" Event delivered late #2358

Closed IronSight87 closed 2 years ago

IronSight87 commented 2 years ago

Hi there,

please see my code example below. I am waiting for a "Mint" event for a LP contract. My callback is fired, but very late. The actual "Mint" event was fired at 2:59:18 PM (UTC) and my function was triggered at 2:59:24 PM (UTC). Meaning a delay of 6 seconds, which is a lot. Futhermore I then triggered a buy action at 2:59:24 PM (UTC) which was completed at 02:59:30 PM (UTC). Meaning another 6 seconds delay. Other buyers (>300) where able to trigger the buy action 1 second after the Mint event occured. Is there some kind of delay in the ethers library? Thank you in advance for your help!

Mint event transaction: https://bscscan.com/tx/0x71206e420491ff872ff135bb1f3f95a8f8658e64e723220f453e24e4bc048e78

const ethers = require('ethers');

// CONFIGURATION
const url = "https://small-damp-shape.bsc.quiknode.pro/<API-Key>/";
const privateKey = "ENTER PRIVATE KEY HERE";
const tokenInAddr = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; // WBNB
const tokenOutAaddr = "0x3465fD2D9f900e34280aBab60E8d9987B5b5bb47"; // DOR
const amountIn = "1"; // WBNB
const gasLimit = 200000;
const gasPrice = 5; // GWEI

var provider = ethers.getDefaultProvider(url);
var wallet = new ethers.Wallet(privateKey, provider);
var account = wallet.address;

const router = new ethers.Contract(
    "0x10ED43C718714eb63d5aA57B78B54704E256024E", // PancakeSwap v2 ROUTER
    [
        'function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts)'
    ],
    wallet
);

const factory = new ethers.Contract(
    "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73", // PancakeSwap v2 FACTORY
    ['function getPair(address tokenA, address tokenB) external view returns (address pair)'],
    wallet
);

const pairAddress = await factory.getPair(tokenInAddr, tokenOutAaddr);
var contract = new ethers.Contract(
    pairAddress,
    [
        'event Mint(address indexed sender, uint amount0, uint amount1)',
    ],
    provider
); 

contract.once("Mint", (sender, amount0, amount1) => {
    console.log("Liquidity was added");

    buyStuff();
});

async function buyStuff() {
    let amountOutWei = ethers.utils.parseUnits(`${amountOut}`, 'ether');
    let amountInWei = ethers.utils.parseUnits(`${amountIn}`, 'ether');
    try {
        const tx = await router.swapExactETHForTokens(
            0,
            [tokenInAddr, tokenOutAaddr],
            account,
            Math.floor(Date.now()/1000) + (60 * 10), 
            {
                'gasLimit': gasLimit, 
                'gasPrice': ethers.utils.parseUnits(`${gasPrice}`, 'gwei'),
                'nonce' : null,
                'value' : amountInWei
            }
        );

        const receipt = await tx.wait();
        console.log(receipt.transactionHash);
    }
    catch(e) {
        console.log(e);
    }
}
ricmoo commented 2 years ago

The default polling period is 4s for polling-based providers. If you reduce that you may incur additional charges from your backend and it is not recommended for the community api keys.

Six seconds is not a long time, but if your application requires low-latency, you should definitely be running your own infrastructure or paying for the higher-tier options for your backend services to achieve them.