Skip to content

Instantly share code, notes, and snippets.

@Anish-Agnihotri
Created September 23, 2021 04:27
Show Gist options
  • Star 90 You must be signed in to star a gist
  • Fork 30 You must be signed in to fork a gist
  • Save Anish-Agnihotri/8c16906310f406d0d79cab0e45594191 to your computer and use it in GitHub Desktop.
Save Anish-Agnihotri/8c16906310f406d0d79cab0e45594191 to your computer and use it in GitHub Desktop.
getting too easy
Times mainnet auction address for tomorrow:
https://etherscan.io/token/0xdd69da9a83cedc730bc4d3c56e96d29acc05ecde
@Anish-Agnihotri
Copy link
Author

Anish-Agnihotri commented Sep 23, 2021

An example script participating in gas auctions:

// Imports
const ethers = require("ethers");

// Times contract
const address = "0xDd69da9a83ceDc730bc4d3C56E96D29Acc05eCDE";
const rpc = new ethers.providers.JsonRpcProvider("http://localhost:8545");
const abi = [
  {
    inputs: [{ internalType: "uint8", name: "amount", type: "uint8" }],
    name: "mintTokens",
    outputs: [],
    stateMutability: "payable",
    type: "function",
  },
  {
    inputs: [{ internalType: "address", name: "owner", type: "address" }],
    name: "balanceOf",
    outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
    stateMutability: "view",
    type: "function",
  },
];
const times = new ethers.Contract(address, abi, rpc);
const startingTimestamp = 1632412800;

// Botting wallet
const privateKey = "";
const wallet = new ethers.Wallet(privateKey);
const timesConnected = times.connect(wallet);

// Script
(async () => {
  // On each block
  rpc.on("block", async (blockNumber) => {
    // Collect block timestamp
    const { timestamp } = await rpc.getBlock(blockNumber);
    // Collect user balance
    const numOwned = (
      await timesConnected.balanceOf(wallet.address)
    ).toNumber();
    console.log(`Block #${blockNumber} balance: ${numOwned} times tokens.`);

    // Check if timestamp is within 15s range
    if (timestamp + 15 >= startingTimestamp && numOwned != 25) {
      // Send mint transactions every proceeding block
      console.log(`Sending transaction in ${blockNumber}.`);
      await timesConnected.mintTokens(25, {
        value: ethers.utils.parseEther("2.5"),
        maxFeePerGas: ethers.utils.parseUnits("500", "gwei"),
        maxPriorityFeePerGas: ethers.utils.parseUnits("500", "gwei"),
      });
    }

    // If success
    if (numOwned == 25) {
      console.log("Successfully exiting");
      process.exit(1);
    }
  });
})();

Ideally, you would use Flashbots with a sufficient bribe to prevent gas costs on the few reverts you'll have participating via optimistic blocktime script.

@Ahmeddh
Copy link

Ahmeddh commented Sep 23, 2021

@Anish-Agnihotri any ideas on how to create a bot fighter in the smart contract to block this type of behavior, and make sure the minting process is decent and front runners don’t have this "privileged access"?

coz this is so unfair and will harm the NFT industry as a whole, I will reach out to the alchemist team to elaborate more on this issue

@kajeagentspi
Copy link

@Anish-Agnihotri any ideas on how to create a bot fighter in the smart contract to block this type of behavior, and make sure the minting process is decent and front runners don’t have this "privileged access"?

coz this is so unfair and will harm the NFT industry as a whole, I will reach out to the alchemist team to elaborate more on this issue

A thing you can do is deploy the contract unverified using a virgin address (no tx on any chains) loaded via Binance/Tornado (as long as they won't know who sent eth) then only verify the contract at announced time.

You can also make a honeypot that mints blank nfts.

But since people are smart they can still mint the second a contract gets verified.

@Ahmeddh
Copy link

Ahmeddh commented Sep 25, 2021

Yeah I don’t think it all leaks, some people are greedy enough to run their bots once the contract has been announced, but I've approached alchemist team and their copper fair launch platform has a way to fight this

@JoneKell
Copy link

JoneKell commented Oct 4, 2021

How can I call method to mint if contract has different method name?

@BlankerL
Copy link

@Anish-Agnihotri any ideas on how to create a bot fighter in the smart contract to block this type of behavior, and make sure the minting process is decent and front runners don’t have this "privileged access"?

coz this is so unfair and will harm the NFT industry as a whole, I will reach out to the alchemist team to elaborate more on this issue

Some smart contracts of recent NFT projects require a signature from the backend, in which the msg.sender and quantities are signed by their private key. On the contract side, they will validate the signature, if the signature is correct, the transaction will be processed.

However, the crawler can also request the signature, and commit the transaction, but more difficult than usual.

@caffeinum
Copy link

Black-hat perspective: how do you extract address from a frontend? Do you do this manually searching for "web3.eth.Contract" etc, debugger breakpoints; Or is there some smart automated way?

@caffeinum
Copy link

Black-hat perspective: how do you extract address from a frontend? Do you do this manually searching for "web3.eth.Contract" etc, debugger breakpoints; Or is there some smart automated way?

Damn, sorry, your second tweet literally answers this:
https://twitter.com/_anishagnihotri/status/1441072865764429825?s=20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment