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

Hi @Truciolonyc, I can’t really help here… These keys serve to have access to on chain datas needed for the auto task to do the job. i try with the script given by @bolo. At first glance it’s seem working but i encounter several time this error :
Date

2020-11-08T14:24:45.029Z
Trigger

schedule
Status
error

Message: Error running autotask: Unhandled

Logs: 2020-11-08T14:24:45.788Z AUTOTASK START
2020-11-08T14:24:47.340Z ERROR Invoke Error {“errorType”:“Error”,“errorMessage”:“failed to meet quorum (method=“getBlockNumber”, params={}, results=[{“provider”:{”_isProvider":true,"_events":,"_emitted":{“block”:-2},“formatter”:{“formats”:{“transaction”:{},“transactionRequest”:{},“receiptLog”:{},“receipt”:{},“block”:{},“blockWithTransactions”:{},“filter”:{},“filterLog”:{}}},“anyNetwork”:false,"_network":{“name”:“homestead”,“chainId”:1,“ensAddress”:“0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e”},"_maxInternalBlockNumber":11217247,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":1604845486309,“connection”:{“url”:“https://cloudflare-eth.com/"},"_nextId":43,"_internalBlockNumber":{},"_fastBlockNumber":11217247,"_fastBlockNumberPromise":{}},“weight”:1,“start”:1604845486224,“result”:11217247},{“provider”:{"_isProvider":true,"_events":[],"_emitted":{“block”:-2},“formatter”:{“formats”:{“transaction”:{},“transactionRequest”:{},“receiptLog”:{},“receipt”:{},“block”:{},“blockWithTransactions”:{},“filter”:{},“filterLog”:{}}},“anyNetwork”:false,"_network":{“name”:“homestead”,“chainId”:1,“ensAddress”:“0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e”},"_maxInternalBlockNumber":-1024,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":0,“connection”:{“url”:“https://mainnet.infura.io/v3/xxxxx”},"_nextId":43,“apiKey”:“xxxxx”,“projectId”:“xxxxx”,“projectSecret”:null,"_internalBlockNumber":{}},“weight”:1,“start”:1604845486224,“error”:{“reason”:"bad response”,“code”:“SERVER_ERROR”,“status”:401,“headers”:{“date”:“Sun, 08 Nov 2020 14:24:46 GMT”,“content-type”:“text/plain; charset=utf-8”,“content-length”:“19”,“connection”:“close”,“vary”:“Origin”,“www-authenticate”:“Basic realm=\“Auth failure, invalid project id\””,“x-content-type-options”:“nosniff”},“body”:“invalid project id\n”,“requestBody”:"{\“method\”:\“eth_blockNumber\”,\“params\”:,\“id\”:42,\“jsonrpc\”:\“2.0\”}",“requestMethod”:“POST”,“url”:"https://mainnet.infura.io/v3/xxxxx"}},{“provider”:{"_isProvider":true,"_events":[],"_emitted":{“block”:-2},“formatter”:{“formats”:{“transaction”:{},“transactionRequest”:{},“receiptLog”:{},“receipt”:{},“block”:{},“blockWithTransactions”:{},“filter”:{},“filterLog”:{}}},“anyNetwork”:false,"_network":{“name”:“homestead”,“chainId”:1,"ensAddress
[…]

Edit : I’ve erased all other references than ETHERSCAN (Alchemy & infura), since then. No more previous errors

Edit 2 : same error just happened.

Did you change this part ?

 const provider = ethers.getDefaultProvider("mainnet", { 
etherscan: "xxxxxx",
alchemy: "xxxxx",
infura: {
  projectId: INFURA_PROJECT_ID,
  projectSecret: INFURA_PROJECT_SECRET,
},
  })

Hey guys. update the script, please update with your own keys

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";
const ETHERSCAN = "XXX";
const ALCHEMY =  "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: ETHERSCAN,
alchemy: ALCHEMY,
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); });
}

Yes I know, I’ve putted my ethers an apy key only. It is mandatory to have an infura key too?

I just create an APY Key with infura. I put it in the script with my etherscan and alchemy one. I will see

Edit :

Autotask run

Date

2020-11-08T21:24:44.245Z

Trigger

manual

Status error

Message: Error running autotask: Unhandled

Logs: 2020-11-08T21:24:45.004Z AUTOTASK START 2020-11-08T21:24:45.735Z AUTOTASK COMPLETE

2 Likes

The modified script looks good to me, @bolo! Thanks for setting it up!

1 Like

HI,

I did enther my infuria Key, I dont have an Alchemy nether and Ethescan…are those mandatory? most of the jobs are process successfully. Should i start seen some credit?
Again, i’m navigate in a totally new world, quite fascinating I should say, forgive my ignorance, but I really want to see if I can make. I will start studying soon…promise. :))

Hi, I have followed the guidance and it works well now, just an amatuer question, How long will it take to see work completed?

I asked the same question. check the answer.
https://forum.openzeppelin.com/t/how-to-use-infura-api-project-id/4471/9?u=bolo . It’s not.

Thanks! You are great help to me

Andrea Nanni
cell: (646) 236-6408

All worked fine…but every job shows not workable? is it normal?

@spalladino got the same scenario. all jobs shows not workable even with periodicity of 1 minute.

1 Like

Hey Bolo, it’s possible that competition is currently so fierce that it’s difficult to land any jobs. There are apparently 600+ registered keepers in the network at the moment. You may need to wait until the network stabilizes and some keepers drop or more jobs come up. I’m curious though if there are any official stats of the state of the keeper network…

like that? https://keep3r.live/
it’s look like always same guys who are able to claim the rewards.

Hey @bolo, thanks for replying. I have an error or is it a bug in the

Keep3rV1Oracle
It throws an error as the status is workable.
the error is
Error: too many arguments: passed to contract (count=1, expectedCount=0, code=UNEXPECTED_ARGUMENT, version=contracts/5.0.2)
at Logger.makeError

Thanks again.

Could someone tell me what the error " failed to meet the quorum" mean?

Ty

Did you use your own key? Because when i use that the error goes, but i got another error which I explained above.
I think this means something related to gas estimation but it should be fixed if you use your own key in the script. As @bolo mentioned in the previous comment.

Yes I am using my own keys.

1 Like

Do you get this error? Then How do you fix it?
Error: too many arguments: passed to contract (count=1, expectedCount=0, code=UNEXPECTED_ARGUMENT, version=contracts/5.0.2)
at Logger.makeError (/opt/nodejs/node_modules/@ethersproject/logger/lib/index.js:179:21)

try that. https://gist.github.com/bolom/8e159ea4a30eb50d8f1f7c1a20e3ef07#file-gistfile1-txt-L42

Sorry for disturbing, but the problem is not about gas estimation it is about Contract argument.
specifically the error is the following:
> INFO Keep3rV1Oracle is workable

2020-11-10T18:10:47.666Z	ERROR	Error: too many arguments: passed to contract (count=1, expectedCount=0, code=UNEXPECTED_ARGUMENT, version=contracts/5.0.

Only happens when Job is workable.
thanks so much for your quick reply @bolo