[Guide] How to run a Keep3r on OpenZeppelin Defender for free

I have got the same error as @Truciolonyc

Message: Error running autotask: Unhandled

Logs: 2020-11-05T01:17:12.687Z	AUTOTASK START
2020-11-05T01:17:14.823Z	ERROR	Invoke Error 	{"errorType":"Error","errorMessage":"invalid ENS name (argument=\"name\", value=undefined, code=INVALID_ARGUMENT, version=providers/5.0.5)","code":"INVALID_ARGUMENT","reason":"invalid ENS name","argument":"name","stack":["Error: invalid ENS name (argument=\"name\", value=undefined, code=INVALID_ARGUMENT, version=providers/5.0.5)","    at Logger.makeError (/opt/nodejs/node_modules/@ethersproject/logger/lib/index.js:179:21)","    at Logger.throwError (/opt/nodejs/node_modules/@ethersproject/logger/lib/index.js:188:20)","    at Logger.throwArgumentError (/opt/nodejs/node_modules/@ethersproject/logger/lib/index.js:191:21)","    at FallbackProvider.<anonymous> (/opt/nodejs/node_modules/@ethersproject/providers/lib/base-provider.js:1340:36)","    at step (/opt/nodejs/node_modules/@ethersproject/providers/lib/base-provider.js:46:23)","    at Object.next (/opt/nodejs/node_modules/@ethersproject/providers/lib/base-provider.js:27:53)","    at fulfilled (/opt/nodejs/node_modules/@ethersproject/providers/lib/base-provider.js:18:58)"]}
2020-11-05T01:17:14.860Z	AUTOTASK COMPLETE
1 Like

@bolo can you try copying the code from the guide into a new Autotask? Apparently another user had a similar problem, and solved it by doing that.

@Truciolonyc can you provide more info? Is there anything else in the logs? Can you try with a fresh autotask? Did you modify the code from the guide?

1 Like

Hi Santiago,

Thank you for your reply.

This is the only line of the error.
I add my keeper address in 2 location
Not sure was a fresh autotask, I will try that

Andrea Nanni
cell: (646) 236-6408

@spalladino working now. thanks

Thank you all working fine,

@spalladino If I may suggest something relatively to the guide & the script proposed. Has you can see,
UniswapOracleV2 job is already deprecated and a lot of new jobs have been added and activated
. The given script is all-in-one and have embedded several jobs in one autotask (bonding & different jobs querying). It may be useful to decompose it or at least proposed some simple script for only one task/Job. I see several advantages to offer these different autotask sample. It will be more manageable/ give more modularity in the long run for keepers to handle changes (addition, suppression or modification of offered jobs). For newbies, it could be use to understand the logic of the script and replicate (or at least try to) it for other task/job.

Anyway. Thanks for the great work already done!

@Elma I agree, it may be easier to split the current Autotask into several different ones. However, since we are now handling bonding+activation of the relayer in the autotask itself, we need to keep a single one running to prevent multiple autotasks trying to activate the same relayer at the same time.

We are working on an interface to decouple this, so you can register your Relayer as a keeper from the Relayer page, and then have the autotask just handle jobs executions. At that point, weā€™ll look into breaking down the monolithic script into multiple ones.

3 Likes

The autotask run, but when some jobs are workable it encounter different issues :
The first one seem related to gas fees estimations see the beginning of the error logs :

Autotask run

Date

2020-11-07T22:30:45.369Z

Trigger

schedule

Status error

Message: Error running autotask: Unhandled

Logs: 2020-11-07T22:30:46.228Z AUTOTASK START 2020-11-07T22:30:48.441Z INFO UniswapV2SlidingOracle is workable 2020-11-07T22:30:49.690Z ERROR Invoke Error {ā€œerrorTypeā€:ā€œErrorā€,ā€œerrorMessageā€:"cannot estimate gas; transaction may fail or may require manual gas limit (error={ā€œreasonā€:ā€œfailed to meet quorumā€,ā€œcodeā€:ā€œSERVER_ERRORā€,ā€œmethodā€:ā€œestimateGasā€,ā€œparamsā€:{ā€œtransactionā€:{ā€œfromā€:ā€œ0xD14dCB37642f3011C4A7326D363EFB0E186DF84fā€,"to

Hi Bolo,

maybe you can help meā€¦my autotask is performing all with success, but i donā€™t see any credit given to meā€¦is it normal?

thanks

hi @Truciolonyc, as i see your autotask doesnā€™t encounter any issue. Did you use the one given in the OpenZepplin guide? If not, can you share your script? Thanks

@Truciolonyc can you share you script?

1 Like

@Bolo, Did you use the script given by the guide or you have developed your own?

@Elma Both. I have 2 autotasks. The one with OpenZepplin seems to have an issue with gas estimation price.

1 Like

Yes, i encounter that specific issue. May you share yours? or at least a basic one which could serve me as a model to learn? If not, I understand. Thanks

sure. @spalladino suggested me to use my own keys. Can you confirm I have did it correctly?

const { ethers } = require("ethers");
const { DefenderRelaySigner } = require('defender-relay-client/lib/ethers');
// Settings edited by user
const INFURA_PROJECT_ID = "xxxx"
const INFURA_PROJECT_SECRET = "xxx"

// ABIs for jobs and registry (contain only the methods needed, not the full ABIs of the contracts)
const ABIs = {
  UniswapV2SlidingOracle: [
{"inputs":[],"name":"workable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"work","outputs":[],"stateMutability":"nonpayable","type":"function"}],
  HegicPoolKeep3r: [{"inputs":[],"name":"workable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"}],
  YearnV1EarnKeep3r: [{"inputs":[],"name":"work","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"workable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}],
  AaveLiquidations: [
{"inputs":[],"name":"workable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"work","outputs":[],"stateMutability":"nonpayable","type":"function"}
  ],
  Registry: [{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"keepers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bonding","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"bond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"bondings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"bonding","type":"address"}],"name":"activate","outputs":[],"stateMutability":"nonpayable","type":"function"}],
}

// Definition for all jobs to execute
const Jobs = [
  { name: 'UniswapV2SlidingOracle', address: '0xd20b88Ca8bF84Ca829f7A9Cf0eC64e2bFE91c204', workableFn: 'workable', workFn: 'work' },
  { name: 'HegicPoolKeep3r',        address: '0x5DDe926b0A31346f2485900C5e64c2577F43F774', workableFn: 'workable', workFn: 'claimRewards' },
  { name: 'YearnV1EarnKeep3r',      address: '0xe7F4ab593aeC81EcA754Da1B3B7cE0C42a13Ec0C', workableFn: 'workable', workFn: 'work' },
];

// Address for the Keeper registry
const RegistryAddress = '0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44';

// Work on jobs if it's needed using a Defender relay signer
async function workIfNeeded(signer, jobs) {
  for (const job of jobs) {
const contract = new ethers.Contract(job.address, ABIs[job.name], signer);
if (isWorkable = await contract[job.workableFn]()) {
  console.log(`${job.name} is workable`);
  const tx = await contract[job.workFn]();
  console.log(`${job.name} worked: ${tx.hash}`);
} else {
  console.log(`${job.name} is not workable`);
}
  }
}

// Register the Defender relay as a keep3r
async function registerKeeper(signer, registry) {
  const keeperAddress = await signer.getAddress();
  const collateralAddress = registry.address;
  const bonding = await registry.bondings(keeperAddress, collateralAddress);

  if (bonding.isZero()) {
// Bond with zero KPR tokens
const collateralAmount = '0x00';
const tx = await registry.bond(collateralAddress, collateralAmount);
console.log(`Bonded relayer: ${tx.hash}`);
  } else if (bonding.lt(parseInt(Date.now() / 1000))) {
// Activate if 3-day waiting period has finished
const tx = await registry.activate(collateralAddress);
console.log(`Activated relayer: ${tx.hash}`);
  } else {
// Wait until can activate
const waitInSeconds = bonding.sub(parseInt(Date.now() / 1000)).toString();
console.log(`Waiting ${waitInSeconds} seconds until activation is available`);
  }
}

// Main function
async function main(signer, jobs, registryAddress) {
  const keeperAddress = await signer.getAddress();
  const registry = new ethers.Contract(registryAddress, ABIs.Registry, signer);

  // Work if this is a registered keeper, or register it otherwise
  if (await registry.keepers(keeperAddress)) {
await workIfNeeded(signer, jobs);
  } else {
await registerKeeper(signer, registry);
  }
}

// Entrypoint for the Autotask
exports.handler = async function(credentials) {
  const provider = ethers.getDefaultProvider("mainnet", { 
etherscan: "xxxxxx",
alchemy: "xxxxx",
infura: {
  projectId: INFURA_PROJECT_ID,
  projectSecret: INFURA_PROJECT_SECRET,
},
  });;
  const signer = new DefenderRelaySigner(credentials, provider, { speed: 'fastest' });
  return await main(signer, Jobs, RegistryAddress);
}

// To run locally (this code will not be executed in Autotasks)
if (require.main === module) {
  require('dotenv').config();
  const { API_KEY: apiKey, API_SECRET: apiSecret } = process.env;
  exports.handler({ apiKey, apiSecret })
.then(() => process.exit(0))
.catch(error => { console.error(error); process.exit(1); });
}
2 Likes

@bolo So youā€™ve added your infura key right? Iā€™ve to remplace it by my own (Iā€™ve an alchemy one)? Thanks a lot
ā€¦

exaclty. I have added my kes for infura, alchemy and etherscan. :wink:

1 Like

With my etherscan APY keys, itā€™s seem working. I will wait for a workable events to see how it will be handled! Thanks a lot again

1 Like

I have the same as you have below, only I donā€™t have the Infuria key. Is this a problem? I have no clue what those keys do. Any help? ty so much

I used the OpenZeppelin one