Total supply of an ERC-721 with autotasks

How can I check the totalSupply of a given ERC-721 contract, let's say every 2h please?

Is it mandatory to use a Relayer or just an AutoTask is enough?

:computer: Environment

From the UI at https://defender.openzeppelin.com/#/autotask/runs

:memo:Details

:1234: Code to reproduce

I tried with a sample code of an ERC-20 contract :

// Import dependencies available in the autotask environment
const { RelayerParams } = require('defender-relay-client/lib/relayer');
const { DefenderRelayProvider } = require('defender-relay-client/lib/ethers');
const { ethers } = require('ethers');

// Import an ABI which will be embedded into the generated js
const ERC20_ABI = [{anonymous:false,inputs:[{indexed:true,internalType:"address",name:"owner",type:"address"},{indexed:true,internalType:"address",name:"spender",type:"address"},{indexed:false,internalType:"uint256",name:"value",type:"uint256"}],name:"Approval",type:"event"},{anonymous:false,inputs:[{indexed:true,internalType:"address",name:"from",type:"address"},{indexed:true,internalType:"address",name:"to",type:"address"},{indexed:false,internalType:"uint256",name:"value",type:"uint256"}],name:"Transfer",type:"event"},{inputs:[{internalType:"address",name:"owner",type:"address"},{internalType:"address",name:"spender",type:"address"}],name:"allowance",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"spender",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"approve",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"}],name:"balanceOf",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[],name:"totalSupply",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"recipient",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transfer",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"sender",type:"address"},{internalType:"address",name:"recipient",type:"address"},{internalType:"uint256",name:"amount",type:"uint256"}],name:"transferFrom",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"nonpayable",type:"function"}];

// Address of the DAI contract (for this example)
const DAI = `0x6b175474e89094c44da98b954eedeac495271d0f`;

// Entrypoint for the Autotask
exports.handler = async function(credentials) {
  const provider = new DefenderRelayProvider(credentials);
  const dai = new ethers.Contract(DAI, ERC20_ABI, provider);
  const atto = await dai.totalSupply();
  const supply = Math.ceil(atto.div(1e18.toString()).toNumber());
  const parity = supply % 2 == 0 ? 'even' : 'odd';
  console.log(`DAI total supply is ${supply} (${parity})`);
}

But I get this error :
Missing required key 'FunctionName' in params

Someone has an idea what did I do wrong please?

Thank you,

Hey @minimoz ,

In doing some testing, it appears that error you are seeing is due to implementing something specific to Defender Relayers (in this case DefenderRelayProvider), but not assigning a Relayer to the Autotask.

Taking the existing code, if you were to just create a Relayer on the desired network (guessing Mainnet) and assign it to an Autotask with this code, it should work. Since it's not executing any operations that require paying gas, the relayer wouldn't need to have a balance.

An alternative would be to use a different JSON RPC provider.

Please let me know if you're having any issues with this.

Thanks!

Dan McKeon
OpenZeppelin

Hey @dan_oz :slight_smile:

Thank you for your prompt response!

Is it mandatory to use DefenderRelayProvider or is there another way to instantiate a provider that doesn't need to perform any Write transaction on-chain?

I'm using Avalanche C-Chain network, but I guess there is no difference regarding your solution, I'll try it too :ok_hand:

Thanks!

Works like a charm when providing a Relay :ok_hand:

Thank you!

Hey there @minimoz ,

Sorry I missed your question a couple days ago!

Providing a Relay works fine, but to your point, you're not actually writing anything so it's not a necessity. One other option would be to create your own JSON RPC node using a service like Alchemy or Infura. Both of their free tiers are fairly generous.

Dan McKeon
OpenZeppelin

Alright, I see what you mean :slight_smile:
I would have to find a provider on Avalanche to get my own JSON RPC, maybe Moralis does it.

Anyway, I'll keep an empty Relay for now!

Thanks,