-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3924134
Showing
1 changed file
with
103 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
const { ethers } = require("ethers"); | ||
const { DefenderRelaySigner } = require('defender-relay-client/lib/ethers'); | ||
// Settings edited by user | ||
|
||
|
||
// ABIs for jobs and registry (contain only the methods needed, not the full ABIs of the contracts) | ||
const ABIs = { | ||
Keep3rV1Oracle: [ | ||
{"inputs":[],"name":"workable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}, | ||
{"inputs":[],"name":"work","outputs":[],"stateMutability":"nonpayable","type":"function"} | ||
], | ||
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"}], | ||
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: 'Keep3rV1Oracle', address: '0x73353801921417f465377c8d898c6f4c0270282c', workableFn: 'workable', workFn: 'work' }, | ||
{ name: 'UniswapV2SlidingOracle', address: '0xCA2E2df6A7a7Cf5bd19D112E8568910a6C2D3885', 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`); | ||
var overrideOptions = {} | ||
try { | ||
const tx = await contract[job.workFn](); | ||
console.log(`${job.name} worked: ${tx.hash}`); | ||
} catch(error) { | ||
console.error(error); | ||
} | ||
} 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: '5AYE5518GVRQ1GK7ZSKQRJXA1DFVV3HEH8', | ||
alchemy: 'u9jyH-D71Z_y9L9K3mn5Ma3gtmRQrbhB', | ||
}); | ||
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); }); | ||
} |